mirror of
https://github.moeyy.xyz/https://github.com/GeWuYou/forgeboot
synced 2025-10-27 19:36:36 +08:00
Merge branch 'refactor/7-mvc-dto-spec-refactoring-mvc-s-dto-and-spec-modules' into 'main'
refactor(webmvc): 重构 Web 项目通用 CRUD 接口规范模块 Closes #7 See merge request gewuyou/forgeboot!12
This commit is contained in:
commit
4a804c4a54
@ -29,6 +29,10 @@ object Modules {
|
|||||||
const val VALIDATION = ":forgeboot-webmvc-spring-boot-starter:forgeboot-webmvc-validation"
|
const val VALIDATION = ":forgeboot-webmvc-spring-boot-starter:forgeboot-webmvc-validation"
|
||||||
const val VERSION = ":forgeboot-webmvc-spring-boot-starter:forgeboot-webmvc-version-spring-boot-starter"
|
const val VERSION = ":forgeboot-webmvc-spring-boot-starter:forgeboot-webmvc-version-spring-boot-starter"
|
||||||
const val LOGGER = ":forgeboot-webmvc-spring-boot-starter:forgeboot-webmvc-logger-spring-boot-starter"
|
const val LOGGER = ":forgeboot-webmvc-spring-boot-starter:forgeboot-webmvc-logger-spring-boot-starter"
|
||||||
|
object Spec{
|
||||||
|
const val CORE = ":forgeboot-webmvc-spring-boot-starter:forgeboot-webmvc-spec-core"
|
||||||
|
const val JPA = ":forgeboot-webmvc-spring-boot-starter:forgeboot-webmvc-spec-jpa"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -7,8 +7,6 @@ dependencies {
|
|||||||
implementation(libs.kotlinReflect)
|
implementation(libs.kotlinReflect)
|
||||||
compileOnly(libs.springBootDependencies.bom)
|
compileOnly(libs.springBootDependencies.bom)
|
||||||
compileOnly(libs.jackson.annotations)
|
compileOnly(libs.jackson.annotations)
|
||||||
compileOnly(libs.springBootStarter.jpa)
|
|
||||||
compileOnly(libs.springBootStarter.validation)
|
|
||||||
}
|
}
|
||||||
i18nKeyGen {
|
i18nKeyGen {
|
||||||
rootPackage.set("com.gewuyou.forgeboot.webmvc.dto.i18n")
|
rootPackage.set("com.gewuyou.forgeboot.webmvc.dto.i18n")
|
||||||
|
|||||||
@ -1,38 +0,0 @@
|
|||||||
package com.gewuyou.forgeboot.webmvc.dto.page
|
|
||||||
|
|
||||||
import jakarta.persistence.criteria.CriteriaBuilder
|
|
||||||
import jakarta.persistence.criteria.Predicate
|
|
||||||
import jakarta.persistence.criteria.Root
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 可过滤接口,用于支持泛型类型的过滤操作
|
|
||||||
*
|
|
||||||
* 该接口定义了过滤功能的基本契约,允许实现类根据给定的过滤条件构建查询规范。
|
|
||||||
* 主要用于与 JPA Criteria API 集成,以构建动态查询条件。
|
|
||||||
*
|
|
||||||
* @param <FilterType> 过滤条件的类型,通常是一个包含过滤参数的数据传输对象(DTO)。
|
|
||||||
* @param <EntityType> 被查询的实体类型,通常对应数据库中的某个实体类。
|
|
||||||
*
|
|
||||||
* @since 2025-07-19 08:56:56
|
|
||||||
* @author gewuyou
|
|
||||||
*/
|
|
||||||
interface Filterable<FilterType, EntityType> : QueryComponent {
|
|
||||||
/**
|
|
||||||
* 获取当前的过滤条件对象。
|
|
||||||
*
|
|
||||||
* @return 返回一个可空的 FilterType 实例,表示当前的过滤条件。
|
|
||||||
*/
|
|
||||||
val filter: FilterType?
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 构建查询条件的谓词列表。
|
|
||||||
*
|
|
||||||
* 此方法根据当前的过滤条件,使用给定的 CriteriaBuilder 创建一组 Predicate 对象,
|
|
||||||
* 这些谓词可以用于构建最终查询语句。
|
|
||||||
*
|
|
||||||
* @param root 代表查询的根实体,用于访问实体的属性。
|
|
||||||
* @param cb CriteriaBuilder 实例,用于创建查询条件。
|
|
||||||
* @return 返回一个包含查询条件的 Predicate 列表。
|
|
||||||
*/
|
|
||||||
fun buildSpecification(root: Root<EntityType>, cb: CriteriaBuilder): List<Predicate>
|
|
||||||
}
|
|
||||||
@ -1,28 +0,0 @@
|
|||||||
package com.gewuyou.forgeboot.webmvc.dto.request
|
|
||||||
|
|
||||||
import com.gewuyou.forgeboot.webmvc.dto.entities.SortCondition
|
|
||||||
import com.gewuyou.forgeboot.webmvc.dto.page.DateRangeFilterable
|
|
||||||
import com.gewuyou.forgeboot.webmvc.dto.page.Filterable
|
|
||||||
import com.gewuyou.forgeboot.webmvc.dto.page.Pageable
|
|
||||||
import com.gewuyou.forgeboot.webmvc.dto.page.Sortable
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 抽象排序日期过滤分页请求基类
|
|
||||||
*
|
|
||||||
* 该抽象类为分页请求提供了基础结构,支持以下功能:
|
|
||||||
* - 分页控制(通过Pageable接口)
|
|
||||||
* - 排序功能(通过Sortable接口)
|
|
||||||
* - 日期范围过滤(通过DateRangeFilterable接口)
|
|
||||||
* - 通用数据过滤(通过Filterable<T,E>接口)
|
|
||||||
*
|
|
||||||
* @property currentPage 当前页码,从1开始计数,默认值为1
|
|
||||||
* @property pageSize 每页记录数,默认值为10
|
|
||||||
*
|
|
||||||
* @since 2025-07-19 14:50:36
|
|
||||||
* @author gewuyou
|
|
||||||
*/
|
|
||||||
abstract class AbstractSortedDateFilterPageRequest<T,E>(
|
|
||||||
override val currentPage: Int = 1,
|
|
||||||
override val pageSize: Int = 10,
|
|
||||||
override val sortConditions: List<SortCondition> = mutableListOf()
|
|
||||||
) : Pageable, Sortable, DateRangeFilterable, Filterable<T,E>
|
|
||||||
3
forgeboot-webmvc/spec-core/build.gradle.kts
Normal file
3
forgeboot-webmvc/spec-core/build.gradle.kts
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
dependencies {
|
||||||
|
|
||||||
|
}
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package com.gewuyou.forgeboot.webmvc.dto.entities
|
package com.gewuyou.webmvc.spec.core.entities
|
||||||
|
|
||||||
import java.time.Instant
|
import java.time.Instant
|
||||||
|
|
||||||
@ -1,6 +1,6 @@
|
|||||||
package com.gewuyou.forgeboot.webmvc.dto.entities
|
package com.gewuyou.webmvc.spec.core.entities
|
||||||
|
|
||||||
import org.hibernate.query.SortDirection
|
import com.gewuyou.webmvc.spec.core.enums.SortDirection
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 排序条件
|
* 排序条件
|
||||||
@ -17,5 +17,5 @@ class SortCondition {
|
|||||||
/**
|
/**
|
||||||
* 排序方向
|
* 排序方向
|
||||||
*/
|
*/
|
||||||
var direction: SortDirection = SortDirection.DESCENDING
|
var direction: SortDirection = SortDirection.DESC
|
||||||
}
|
}
|
||||||
@ -0,0 +1,64 @@
|
|||||||
|
package com.gewuyou.webmvc.spec.core.enums
|
||||||
|
|
||||||
|
import java.util.Locale
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 排序方向枚举
|
||||||
|
*
|
||||||
|
* @author gewuyou
|
||||||
|
* @since 2025-01-16 17:56:01
|
||||||
|
*/
|
||||||
|
enum class SortDirection {
|
||||||
|
ASC, DESC;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取当前排序方向的反方向
|
||||||
|
*
|
||||||
|
* @return 返回与当前方向相反的排序方向枚举值
|
||||||
|
* - 当前为ASC时返回DESC
|
||||||
|
* - 当前为DESC时返回ASC
|
||||||
|
*/
|
||||||
|
fun reverse(): SortDirection = when (this) {
|
||||||
|
ASC -> DESC
|
||||||
|
DESC -> ASC
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
/**
|
||||||
|
* 将字符串解析为排序方向枚举值(忽略大小写)
|
||||||
|
*
|
||||||
|
* 支持的输入包括:
|
||||||
|
* - "asc", "ascending" → ASC
|
||||||
|
* - "desc", "descending" → DESC
|
||||||
|
*
|
||||||
|
* @param value 待解析的字符串,可为空
|
||||||
|
* @return 解析成功返回对应的枚举值,value为空时返回null,无法解析时抛出异常
|
||||||
|
* @throws IllegalArgumentException 当输入字符串无法识别为有效的排序方向时
|
||||||
|
*/
|
||||||
|
@JvmStatic
|
||||||
|
fun interpret(value: String?): SortDirection? {
|
||||||
|
if (value == null) return null
|
||||||
|
return when (value.lowercase(Locale.ROOT)) {
|
||||||
|
"asc", "ascending" -> ASC
|
||||||
|
"desc", "descending" -> DESC
|
||||||
|
else -> throw IllegalArgumentException("Unknown sort direction: $value")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 安全地将字符串解析为排序方向枚举值,如果解析失败则返回默认值
|
||||||
|
*
|
||||||
|
* @param value 待解析的字符串,可为空
|
||||||
|
* @param default 解析失败时返回的默认值,默认为ASC
|
||||||
|
* @return 解析成功返回对应的枚举值,解析失败或value为空时返回默认值
|
||||||
|
*/
|
||||||
|
fun interpretOrDefault(value: String?, default: SortDirection = ASC): SortDirection {
|
||||||
|
return try {
|
||||||
|
interpret(value) ?: default
|
||||||
|
} catch (_: IllegalArgumentException) {
|
||||||
|
default
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -1,6 +1,7 @@
|
|||||||
package com.gewuyou.forgeboot.webmvc.dto.page
|
package com.gewuyou.webmvc.spec.core.page
|
||||||
|
|
||||||
|
import com.gewuyou.webmvc.spec.core.entities.DateRangeCondition
|
||||||
|
|
||||||
import com.gewuyou.forgeboot.webmvc.dto.entities.DateRangeCondition
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 日期范围可过滤接口
|
* 日期范围可过滤接口
|
||||||
@ -0,0 +1,19 @@
|
|||||||
|
package com.gewuyou.webmvc.spec.core.page
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 可过滤接口,用于支持泛型类型的过滤操作
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param <FilterType> 过滤条件的类型,通常是一个包含过滤参数的数据传输对象(DTO)。
|
||||||
|
*
|
||||||
|
* @since 2025-07-19 08:56:56
|
||||||
|
* @author gewuyou
|
||||||
|
*/
|
||||||
|
interface Filterable<FilterType> : QueryComponent {
|
||||||
|
/**
|
||||||
|
* 获取当前的过滤条件对象。
|
||||||
|
*
|
||||||
|
* @return 返回一个可空的 FilterType 实例,表示当前的过滤条件。
|
||||||
|
*/
|
||||||
|
val filter: FilterType?
|
||||||
|
}
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package com.gewuyou.forgeboot.webmvc.dto.page
|
package com.gewuyou.webmvc.spec.core.page
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 关键字可搜索接口,用于支持包含关键字搜索条件的数据结构
|
* 关键字可搜索接口,用于支持包含关键字搜索条件的数据结构
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package com.gewuyou.forgeboot.webmvc.dto.page
|
package com.gewuyou.webmvc.spec.core.page
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 可分页接口,用于支持分页功能的类实现
|
* 可分页接口,用于支持分页功能的类实现
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package com.gewuyou.forgeboot.webmvc.dto.page
|
package com.gewuyou.webmvc.spec.core.page
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* QueryComponent 是一个密封接口,用于定义查询组件的公共契约。
|
* QueryComponent 是一个密封接口,用于定义查询组件的公共契约。
|
||||||
@ -1,7 +1,7 @@
|
|||||||
package com.gewuyou.forgeboot.webmvc.dto.page
|
package com.gewuyou.webmvc.spec.core.page
|
||||||
|
|
||||||
import com.gewuyou.forgeboot.webmvc.dto.entities.SortCondition
|
import com.gewuyou.webmvc.spec.core.entities.SortCondition
|
||||||
import org.hibernate.query.SortDirection
|
import com.gewuyou.webmvc.spec.core.enums.SortDirection
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 可排序接口,用于定义排序相关属性
|
* 可排序接口,用于定义排序相关属性
|
||||||
@ -0,0 +1,10 @@
|
|||||||
|
package com.gewuyou.webmvc.spec.core.page
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 启用状态可过滤接口,用于支持启用/禁用状态的过滤功能。
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @since 2025-07-19 09:00:42
|
||||||
|
* @author gewuyou
|
||||||
|
*/
|
||||||
|
interface StatusFilterable : QueryComponent
|
||||||
@ -1,7 +1,8 @@
|
|||||||
package com.gewuyou.forgeboot.webmvc.dto.request
|
package com.gewuyou.webmvc.spec.core.request
|
||||||
|
|
||||||
|
import com.gewuyou.webmvc.spec.core.page.DateRangeFilterable
|
||||||
|
import com.gewuyou.webmvc.spec.core.page.Pageable
|
||||||
|
|
||||||
import com.gewuyou.forgeboot.webmvc.dto.page.DateRangeFilterable
|
|
||||||
import com.gewuyou.forgeboot.webmvc.dto.page.Pageable
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 抽象日期分页请求
|
* 抽象日期分页请求
|
||||||
@ -1,8 +1,9 @@
|
|||||||
package com.gewuyou.forgeboot.webmvc.dto.request
|
package com.gewuyou.webmvc.spec.core.request
|
||||||
|
|
||||||
|
import com.gewuyou.webmvc.spec.core.page.DateRangeFilterable
|
||||||
|
import com.gewuyou.webmvc.spec.core.page.Pageable
|
||||||
|
import com.gewuyou.webmvc.spec.core.page.StatusFilterable
|
||||||
|
|
||||||
import com.gewuyou.forgeboot.webmvc.dto.page.DateRangeFilterable
|
|
||||||
import com.gewuyou.forgeboot.webmvc.dto.page.Pageable
|
|
||||||
import com.gewuyou.forgeboot.webmvc.dto.page.StatusFilterable
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 日期状态页面请求
|
* 日期状态页面请求
|
||||||
@ -1,7 +1,8 @@
|
|||||||
package com.gewuyou.forgeboot.webmvc.dto.request
|
package com.gewuyou.webmvc.spec.core.request
|
||||||
|
|
||||||
|
import com.gewuyou.webmvc.spec.core.page.KeywordSearchable
|
||||||
|
import com.gewuyou.webmvc.spec.core.page.Pageable
|
||||||
|
|
||||||
import com.gewuyou.forgeboot.webmvc.dto.page.KeywordSearchable
|
|
||||||
import com.gewuyou.forgeboot.webmvc.dto.page.Pageable
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 抽象搜索分页请求类
|
* 抽象搜索分页请求类
|
||||||
@ -1,8 +1,9 @@
|
|||||||
package com.gewuyou.forgeboot.webmvc.dto.request
|
package com.gewuyou.webmvc.spec.core.request
|
||||||
|
|
||||||
|
import com.gewuyou.webmvc.spec.core.page.DateRangeFilterable
|
||||||
|
import com.gewuyou.webmvc.spec.core.page.Pageable
|
||||||
|
import com.gewuyou.webmvc.spec.core.page.Sortable
|
||||||
|
|
||||||
import com.gewuyou.forgeboot.webmvc.dto.page.DateRangeFilterable
|
|
||||||
import com.gewuyou.forgeboot.webmvc.dto.page.Pageable
|
|
||||||
import com.gewuyou.forgeboot.webmvc.dto.page.Sortable
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 抽象排序日期分页请求
|
* 抽象排序日期分页请求
|
||||||
@ -1,7 +1,8 @@
|
|||||||
package com.gewuyou.forgeboot.webmvc.dto.request
|
package com.gewuyou.webmvc.spec.core.request
|
||||||
|
|
||||||
|
import com.gewuyou.webmvc.spec.core.page.Pageable
|
||||||
|
import com.gewuyou.webmvc.spec.core.page.Sortable
|
||||||
|
|
||||||
import com.gewuyou.forgeboot.webmvc.dto.page.Pageable
|
|
||||||
import com.gewuyou.forgeboot.webmvc.dto.page.Sortable
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 抽象排序分页请求数据类
|
* 抽象排序分页请求数据类
|
||||||
@ -1,6 +1,7 @@
|
|||||||
package com.gewuyou.forgeboot.webmvc.dto.request
|
package com.gewuyou.webmvc.spec.core.request
|
||||||
|
|
||||||
|
import com.gewuyou.webmvc.spec.core.page.Pageable
|
||||||
|
|
||||||
import com.gewuyou.forgeboot.webmvc.dto.page.Pageable
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 基本分页请求数据类
|
* 基本分页请求数据类
|
||||||
@ -1,7 +1,4 @@
|
|||||||
package com.gewuyou.forgeboot.webmvc.dto.request
|
package com.gewuyou.webmvc.spec.core.request
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties
|
|
||||||
import jakarta.validation.constraints.NotEmpty
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 根据id列表删除请求
|
* 根据id列表删除请求
|
||||||
@ -12,16 +9,13 @@ import jakarta.validation.constraints.NotEmpty
|
|||||||
* @author gewuyou
|
* @author gewuyou
|
||||||
* @since 2025-01-18 17:39:18
|
* @since 2025-01-18 17:39:18
|
||||||
*/
|
*/
|
||||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
|
||||||
open class DeleteByIdsReq<T>(
|
open class DeleteByIdsReq<T>(
|
||||||
/**
|
/**
|
||||||
* 待删除的实体id列表
|
* 待删除的实体id列表
|
||||||
*
|
*
|
||||||
* 这个字段是删除操作的核心参数,它不能为空,以确保至少有一个id被指定用于删除
|
* 这个字段是删除操作的核心参数,它不能为空,以确保至少有一个id被指定用于删除
|
||||||
* 使用@NotNull注解来确保在序列化和反序列化过程中,该字段不能为空
|
|
||||||
*
|
*
|
||||||
* @param ids 实体的唯一标识符列表,用于指定哪些实体应当被删除
|
* @param ids 实体的唯一标识符列表,用于指定哪些实体应当被删除
|
||||||
*/
|
*/
|
||||||
@field:NotEmpty(message = "The list of Ids requested to be removed cannot be empty!")
|
|
||||||
var ids: List<T>,
|
var ids: List<T>,
|
||||||
)
|
)
|
||||||
3
forgeboot-webmvc/spec-jpa/.gitattributes
vendored
Normal file
3
forgeboot-webmvc/spec-jpa/.gitattributes
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
/gradlew text eol=lf
|
||||||
|
*.bat text eol=crlf
|
||||||
|
*.jar binary
|
||||||
40
forgeboot-webmvc/spec-jpa/.gitignore
vendored
Normal file
40
forgeboot-webmvc/spec-jpa/.gitignore
vendored
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
HELP.md
|
||||||
|
.gradle
|
||||||
|
build/
|
||||||
|
!gradle/wrapper/gradle-wrapper.jar
|
||||||
|
!**/src/main/**/build/
|
||||||
|
!**/src/test/**/build/
|
||||||
|
|
||||||
|
### STS ###
|
||||||
|
.apt_generated
|
||||||
|
.classpath
|
||||||
|
.factorypath
|
||||||
|
.project
|
||||||
|
.settings
|
||||||
|
.springBeans
|
||||||
|
.sts4-cache
|
||||||
|
bin/
|
||||||
|
!**/src/main/**/bin/
|
||||||
|
!**/src/test/**/bin/
|
||||||
|
|
||||||
|
### IntelliJ IDEA ###
|
||||||
|
.idea
|
||||||
|
*.iws
|
||||||
|
*.iml
|
||||||
|
*.ipr
|
||||||
|
out/
|
||||||
|
!**/src/main/**/out/
|
||||||
|
!**/src/test/**/out/
|
||||||
|
|
||||||
|
### NetBeans ###
|
||||||
|
/nbproject/private/
|
||||||
|
/nbbuild/
|
||||||
|
/dist/
|
||||||
|
/nbdist/
|
||||||
|
/.nb-gradle/
|
||||||
|
|
||||||
|
### VS Code ###
|
||||||
|
.vscode/
|
||||||
|
|
||||||
|
### Kotlin ###
|
||||||
|
.kotlin
|
||||||
@ -1,6 +1,5 @@
|
|||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
compileOnly(libs.springBootStarter.jpa)
|
|
||||||
api(project(Modules.Webmvc.DTO))
|
api(project(Modules.Webmvc.DTO))
|
||||||
api(project(Modules.Core.EXTENSION))
|
api(project(Modules.Webmvc.Spec.CORE))
|
||||||
|
compileOnly(libs.springBootStarter.jpa)
|
||||||
}
|
}
|
||||||
@ -1,22 +1,31 @@
|
|||||||
package com.gewuyou.forgeboot.webmvc.dto.extension
|
package com.gewuyou.webmvc.spec.jpa.extension
|
||||||
|
|
||||||
import com.gewuyou.forgeboot.webmvc.dto.page.*
|
|
||||||
|
import com.gewuyou.webmvc.spec.core.enums.SortDirection
|
||||||
|
import com.gewuyou.webmvc.spec.core.page.DateRangeFilterable
|
||||||
|
import com.gewuyou.webmvc.spec.core.page.KeywordSearchable
|
||||||
|
import com.gewuyou.webmvc.spec.core.page.Pageable
|
||||||
|
import com.gewuyou.webmvc.spec.core.page.QueryComponent
|
||||||
|
import com.gewuyou.webmvc.spec.core.page.Sortable
|
||||||
|
import com.gewuyou.webmvc.spec.jpa.page.JpaFilterable
|
||||||
|
import com.gewuyou.webmvc.spec.jpa.page.JpaStatusFilterable
|
||||||
import jakarta.persistence.criteria.CriteriaBuilder
|
import jakarta.persistence.criteria.CriteriaBuilder
|
||||||
import jakarta.persistence.criteria.Predicate
|
import jakarta.persistence.criteria.Predicate
|
||||||
import jakarta.persistence.criteria.Root
|
import jakarta.persistence.criteria.Root
|
||||||
import org.hibernate.query.SortDirection
|
|
||||||
import org.springframework.data.domain.PageRequest
|
import org.springframework.data.domain.PageRequest
|
||||||
import org.springframework.data.domain.Sort
|
import org.springframework.data.domain.Sort
|
||||||
import org.springframework.data.jpa.domain.Specification
|
import org.springframework.data.jpa.domain.Specification
|
||||||
import java.time.Instant
|
import java.time.Instant
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 将 Hibernate 的 SortDirection 转换为 Spring Data 的 Sort.Direction。
|
* 将自定义的排序方向枚举转换为 Spring Data JPA 的排序方向
|
||||||
*
|
*
|
||||||
* @return 返回对应的 Sort.Direction 实例
|
* @return 对应的 Spring Data Sort.Direction 枚举值
|
||||||
*/
|
*/
|
||||||
fun SortDirection.toSpringDirection(): Sort.Direction =
|
fun SortDirection.toSpringDirection(): Sort.Direction =
|
||||||
if (this == SortDirection.DESCENDING) Sort.Direction.DESC else Sort.Direction.ASC
|
if (this == SortDirection.DESC) Sort.Direction.DESC else Sort.Direction.ASC
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 将当前排序配置转换为可用于 Spring Data Pageable 的排序条件列表
|
* 将当前排序配置转换为可用于 Spring Data Pageable 的排序条件列表
|
||||||
@ -140,17 +149,17 @@ fun <T> QueryComponent.toSpecification(): Specification<T> {
|
|||||||
(this as? DateRangeFilterable)?.let {
|
(this as? DateRangeFilterable)?.let {
|
||||||
predicates += it.buildDateRangePredicates(root, cb)
|
predicates += it.buildDateRangePredicates(root, cb)
|
||||||
}
|
}
|
||||||
// 判断并组合 Status
|
// 判断并组合 JpaStatusFilterable
|
||||||
(this as? StatusFilterable)?.let {
|
(this as? JpaStatusFilterable)?.let {
|
||||||
predicates += it.buildStatusPredicates(root, cb)
|
predicates += it.buildStatusPredicates(root, cb)
|
||||||
}
|
}
|
||||||
// 判断并组合 KeywordSearchable
|
// 判断并组合 KeywordSearchable
|
||||||
(this as? KeywordSearchable)?.let {
|
(this as? KeywordSearchable)?.let {
|
||||||
predicates += it.buildKeywordPredicates(root, cb)
|
predicates += it.buildKeywordPredicates(root, cb)
|
||||||
}
|
}
|
||||||
// 判断并组合 Filterable
|
// 判断并组合 JpaFilterable
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
(this as? Filterable<*, T>)?.let {
|
(this as? JpaFilterable<*, T>)?.let {
|
||||||
predicates += it.buildSpecification(root, cb)
|
predicates += it.buildSpecification(root, cb)
|
||||||
}
|
}
|
||||||
// 组合所有查询条件,返回逻辑 AND 结果
|
// 组合所有查询条件,返回逻辑 AND 结果
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package com.gewuyou.forgeboot.webmvc.dto.extension
|
package com.gewuyou.webmvc.spec.jpa.extension
|
||||||
|
|
||||||
import com.gewuyou.forgeboot.webmvc.dto.PageResult
|
import com.gewuyou.forgeboot.webmvc.dto.PageResult
|
||||||
import org.springframework.data.domain.Page
|
import org.springframework.data.domain.Page
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package com.gewuyou.forgeboot.webmvc.dto.extension
|
package com.gewuyou.webmvc.spec.jpa.extension
|
||||||
|
|
||||||
import com.gewuyou.forgeboot.webmvc.dto.PageResult
|
import com.gewuyou.forgeboot.webmvc.dto.PageResult
|
||||||
|
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package com.gewuyou.forgeboot.webmvc.dto.extension
|
package com.gewuyou.webmvc.spec.jpa.extension
|
||||||
|
|
||||||
import jakarta.persistence.criteria.Predicate
|
import jakarta.persistence.criteria.Predicate
|
||||||
|
|
||||||
@ -0,0 +1,26 @@
|
|||||||
|
package com.gewuyou.webmvc.spec.jpa.page
|
||||||
|
|
||||||
|
import com.gewuyou.webmvc.spec.core.page.Filterable
|
||||||
|
import jakarta.persistence.criteria.CriteriaBuilder
|
||||||
|
import jakarta.persistence.criteria.Predicate
|
||||||
|
import jakarta.persistence.criteria.Root
|
||||||
|
|
||||||
|
/**
|
||||||
|
*JPA可过滤接口
|
||||||
|
*
|
||||||
|
* @since 2025-07-24 21:40:33
|
||||||
|
* @author gewuyou
|
||||||
|
*/
|
||||||
|
interface JpaFilterable<FilterType, EntityType> : Filterable<FilterType> {
|
||||||
|
/**
|
||||||
|
* 构建JPA查询条件规范
|
||||||
|
*
|
||||||
|
* 根据当前过滤条件构建JPA Criteria查询所需的谓词列表,用于动态生成查询条件。
|
||||||
|
* 这些谓词将被用于构建最终的JPA查询语句。
|
||||||
|
*
|
||||||
|
* @param root 查询根对象,用于访问实体属性
|
||||||
|
* @param cb CriteriaBuilder对象,用于创建查询条件谓词
|
||||||
|
* @return 包含查询条件谓词的列表
|
||||||
|
*/
|
||||||
|
fun buildSpecification(root: Root<EntityType>, cb: CriteriaBuilder): List<Predicate>
|
||||||
|
}
|
||||||
@ -1,19 +1,19 @@
|
|||||||
package com.gewuyou.forgeboot.webmvc.dto.page
|
package com.gewuyou.webmvc.spec.jpa.page
|
||||||
|
|
||||||
|
import com.gewuyou.webmvc.spec.core.page.StatusFilterable
|
||||||
import jakarta.persistence.criteria.CriteriaBuilder
|
import jakarta.persistence.criteria.CriteriaBuilder
|
||||||
import jakarta.persistence.criteria.Predicate
|
import jakarta.persistence.criteria.Predicate
|
||||||
import jakarta.persistence.criteria.Root
|
import jakarta.persistence.criteria.Root
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 启用状态可过滤接口,用于支持启用/禁用状态的过滤功能。
|
* 启用状态可过滤接口,用于支持启用/禁用状态的过滤功能。
|
||||||
*
|
*
|
||||||
* 此接口定义了构建状态过滤条件的方法,适用于基于 JPA Criteria API 的查询构建。
|
|
||||||
* 实现该接口的类可通过 [buildStatusPredicates]方法提供具体过滤逻辑。
|
|
||||||
*
|
*
|
||||||
* @since 2025-07-19 09:00:42
|
* @since 2025-07-19 09:00:42
|
||||||
* @author gewuyou
|
* @author gewuyou
|
||||||
*/
|
*/
|
||||||
interface StatusFilterable : QueryComponent {
|
interface JpaStatusFilterable : StatusFilterable{
|
||||||
/**
|
/**
|
||||||
* 构建与启用状态相关的查询条件列表。
|
* 构建与启用状态相关的查询条件列表。
|
||||||
*
|
*
|
||||||
@ -1,12 +1,12 @@
|
|||||||
package com.gewuyou.forgeboot.webmvc.spec.repository
|
package com.gewuyou.webmvc.spec.jpa.repository
|
||||||
|
|
||||||
import org.springframework.data.jpa.repository.JpaRepository
|
import org.springframework.data.jpa.repository.JpaRepository
|
||||||
import org.springframework.data.jpa.repository.JpaSpecificationExecutor
|
import org.springframework.data.jpa.repository.JpaSpecificationExecutor
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*CRUD 存储库规范
|
* Jpa CRUD 存储库规范
|
||||||
*
|
*
|
||||||
* @since 2025-05-29 20:39:11
|
* @since 2025-05-29 20:39:11
|
||||||
* @author gewuyou
|
* @author gewuyou
|
||||||
*/
|
*/
|
||||||
interface CrudRepositorySpec<Entity, Id>: JpaRepository<Entity, Id>, JpaSpecificationExecutor<Entity>
|
interface JpaCrudRepositorySpec<Entity, Id>: JpaRepository<Entity, Id>, JpaSpecificationExecutor<Entity>
|
||||||
@ -1,7 +1,9 @@
|
|||||||
package com.gewuyou.forgeboot.webmvc.dto.request
|
package com.gewuyou.webmvc.spec.jpa.request
|
||||||
|
|
||||||
import com.gewuyou.forgeboot.webmvc.dto.page.Filterable
|
|
||||||
import com.gewuyou.forgeboot.webmvc.dto.page.Pageable
|
import com.gewuyou.webmvc.spec.core.page.Pageable
|
||||||
|
import com.gewuyou.webmvc.spec.jpa.page.JpaFilterable
|
||||||
|
import org.hibernate.query.SortDirection
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -16,8 +18,9 @@ import com.gewuyou.forgeboot.webmvc.dto.page.Pageable
|
|||||||
* @since 2025-07-19 09:16:36
|
* @since 2025-07-19 09:16:36
|
||||||
* @author gewuyou
|
* @author gewuyou
|
||||||
*/
|
*/
|
||||||
abstract class AbstractFilteredPageRequest<T,E>(
|
abstract class AbstractFilteredPageRequest<T, E>(
|
||||||
override val currentPage: Int = 1,
|
override val currentPage: Int = 1,
|
||||||
override val pageSize: Int = 10,
|
override val pageSize: Int = 10,
|
||||||
override val filter: T? = null,
|
override val filter: T? = null,
|
||||||
) : Pageable, Filterable<T,E>
|
sortDirection: SortDirection
|
||||||
|
) : Pageable, JpaFilterable<T, E>
|
||||||
@ -1,6 +1,12 @@
|
|||||||
package com.gewuyou.forgeboot.webmvc.dto.request
|
package com.gewuyou.webmvc.spec.jpa.request
|
||||||
|
|
||||||
import com.gewuyou.forgeboot.webmvc.dto.page.*
|
|
||||||
|
import com.gewuyou.webmvc.spec.core.page.DateRangeFilterable
|
||||||
|
import com.gewuyou.webmvc.spec.core.page.KeywordSearchable
|
||||||
|
import com.gewuyou.webmvc.spec.core.page.Pageable
|
||||||
|
import com.gewuyou.webmvc.spec.core.page.Sortable
|
||||||
|
import com.gewuyou.webmvc.spec.core.page.StatusFilterable
|
||||||
|
import com.gewuyou.webmvc.spec.jpa.page.JpaFilterable
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 抽象分页请求类,用于封装分页查询的通用参数
|
* 抽象分页请求类,用于封装分页查询的通用参数
|
||||||
@ -11,9 +17,6 @@ import com.gewuyou.forgeboot.webmvc.dto.page.*
|
|||||||
*
|
*
|
||||||
* @property currentPage 当前页码,默认值为1
|
* @property currentPage 当前页码,默认值为1
|
||||||
* @property pageSize 每页记录数,默认值为10
|
* @property pageSize 每页记录数,默认值为10
|
||||||
* @property sortBy 排序字段,默认值为"createdAt"
|
|
||||||
* @property sortDirection 排序方向,默认值为降序(SortDirection.DESCENDING)
|
|
||||||
* @property sortConditions 排序条件列表,默认为空列表
|
|
||||||
* @property keyword 关键词搜索内容,可为空
|
* @property keyword 关键词搜索内容,可为空
|
||||||
* @property filter 自定义过滤条件,可为空,类型为泛型T
|
* @property filter 自定义过滤条件,可为空,类型为泛型T
|
||||||
*
|
*
|
||||||
@ -28,6 +31,6 @@ abstract class AbstractFullPageRequest<T,E>(
|
|||||||
) : Pageable,
|
) : Pageable,
|
||||||
Sortable,
|
Sortable,
|
||||||
KeywordSearchable,
|
KeywordSearchable,
|
||||||
Filterable<T,E>,
|
JpaFilterable<T, E>,
|
||||||
DateRangeFilterable,
|
DateRangeFilterable,
|
||||||
StatusFilterable
|
StatusFilterable
|
||||||
@ -1,8 +1,9 @@
|
|||||||
package com.gewuyou.forgeboot.webmvc.dto.request
|
package com.gewuyou.webmvc.spec.jpa.request
|
||||||
|
|
||||||
import com.gewuyou.forgeboot.webmvc.dto.page.Filterable
|
|
||||||
import com.gewuyou.forgeboot.webmvc.dto.page.KeywordSearchable
|
import com.gewuyou.webmvc.spec.core.page.KeywordSearchable
|
||||||
import com.gewuyou.forgeboot.webmvc.dto.page.Pageable
|
import com.gewuyou.webmvc.spec.core.page.Pageable
|
||||||
|
import com.gewuyou.webmvc.spec.jpa.page.JpaFilterable
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 抽象搜索过滤分页请求
|
* 抽象搜索过滤分页请求
|
||||||
@ -18,9 +19,9 @@ import com.gewuyou.forgeboot.webmvc.dto.page.Pageable
|
|||||||
* @since 2025-07-19 10:22:41
|
* @since 2025-07-19 10:22:41
|
||||||
* @author gewuyou
|
* @author gewuyou
|
||||||
*/
|
*/
|
||||||
abstract class AbstractSearchFilterPageRequest<T,E>(
|
abstract class AbstractSearchFilterPageRequest<T, E>(
|
||||||
override val currentPage: Int = 1,
|
override val currentPage: Int = 1,
|
||||||
override val pageSize: Int = 10,
|
override val pageSize: Int = 10,
|
||||||
override val keyword: String? = null,
|
override val keyword: String? = null,
|
||||||
override val filter: T? = null,
|
override val filter: T? = null,
|
||||||
) : Pageable, KeywordSearchable, Filterable<T,E>
|
) : Pageable, KeywordSearchable, JpaFilterable<T, E>
|
||||||
@ -0,0 +1,29 @@
|
|||||||
|
package com.gewuyou.webmvc.spec.jpa.request
|
||||||
|
|
||||||
|
|
||||||
|
import com.gewuyou.webmvc.spec.core.entities.SortCondition
|
||||||
|
import com.gewuyou.webmvc.spec.core.page.DateRangeFilterable
|
||||||
|
import com.gewuyou.webmvc.spec.core.page.Pageable
|
||||||
|
import com.gewuyou.webmvc.spec.core.page.Sortable
|
||||||
|
import com.gewuyou.webmvc.spec.jpa.page.JpaFilterable
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 抽象排序日期过滤分页请求基类
|
||||||
|
*
|
||||||
|
* 该抽象类为分页请求提供了基础结构,支持以下功能:
|
||||||
|
* - 分页控制(通过[Pageable]接口)
|
||||||
|
* - 排序功能(通过[Sortable]接口)
|
||||||
|
* - 日期范围过滤(通过[DateRangeFilterable]接口)
|
||||||
|
* - 通用数据过滤(通过[JpaFilterable]<T,E>接口)
|
||||||
|
*
|
||||||
|
* @property currentPage 当前页码,从1开始计数,默认值为1
|
||||||
|
* @property pageSize 每页记录数,默认值为10
|
||||||
|
*
|
||||||
|
* @since 2025-07-19 14:50:36
|
||||||
|
* @author gewuyou
|
||||||
|
*/
|
||||||
|
abstract class AbstractSortedDateFilterPageRequest<T, E>(
|
||||||
|
override val currentPage: Int = 1,
|
||||||
|
override val pageSize: Int = 10,
|
||||||
|
override val sortConditions: List<SortCondition> = mutableListOf(),
|
||||||
|
) : Pageable, Sortable, DateRangeFilterable, JpaFilterable<T, E>
|
||||||
@ -1,10 +1,11 @@
|
|||||||
package com.gewuyou.forgeboot.webmvc.spec.service
|
package com.gewuyou.webmvc.spec.jpa.service
|
||||||
|
|
||||||
import com.gewuyou.forgeboot.webmvc.dto.PageResult
|
import com.gewuyou.forgeboot.webmvc.dto.PageResult
|
||||||
import com.gewuyou.forgeboot.webmvc.dto.page.QueryComponent
|
import com.gewuyou.webmvc.spec.core.page.QueryComponent
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* CRUD 服务规范
|
* Jpa CRUD 服务规范
|
||||||
*
|
*
|
||||||
* 定义了对实体进行基本操作的服务接口,包括增删查改和分页查询等功能
|
* 定义了对实体进行基本操作的服务接口,包括增删查改和分页查询等功能
|
||||||
*
|
*
|
||||||
@ -13,7 +14,7 @@ import com.gewuyou.forgeboot.webmvc.dto.page.QueryComponent
|
|||||||
* @since 2025-05-29 20:18:22
|
* @since 2025-05-29 20:18:22
|
||||||
* @author gewuyou
|
* @author gewuyou
|
||||||
*/
|
*/
|
||||||
interface CrudServiceSpec<Entity: Any, Id: Any> {
|
interface JpaCrudServiceSpec<Entity: Any, Id: Any> {
|
||||||
/**
|
/**
|
||||||
* 根据ID获取实体
|
* 根据ID获取实体
|
||||||
*
|
*
|
||||||
@ -1,24 +1,25 @@
|
|||||||
package com.gewuyou.forgeboot.webmvc.spec.service.impl
|
package com.gewuyou.webmvc.spec.jpa.service.impl
|
||||||
|
|
||||||
import com.gewuyou.forgeboot.webmvc.dto.PageResult
|
import com.gewuyou.forgeboot.webmvc.dto.PageResult
|
||||||
import com.gewuyou.forgeboot.webmvc.dto.extension.map
|
|
||||||
import com.gewuyou.forgeboot.webmvc.dto.extension.toJpaQuery
|
import com.gewuyou.webmvc.spec.core.page.QueryComponent
|
||||||
import com.gewuyou.forgeboot.webmvc.dto.extension.toPageResult
|
import com.gewuyou.webmvc.spec.jpa.extension.map
|
||||||
import com.gewuyou.forgeboot.webmvc.dto.extension.toSpecification
|
import com.gewuyou.webmvc.spec.jpa.extension.toJpaQuery
|
||||||
import com.gewuyou.forgeboot.webmvc.dto.page.QueryComponent
|
import com.gewuyou.webmvc.spec.jpa.extension.toPageResult
|
||||||
import com.gewuyou.forgeboot.webmvc.spec.repository.CrudRepositorySpec
|
import com.gewuyou.webmvc.spec.jpa.extension.toSpecification
|
||||||
import com.gewuyou.forgeboot.webmvc.spec.service.CrudServiceSpec
|
import com.gewuyou.webmvc.spec.jpa.repository.JpaCrudRepositorySpec
|
||||||
|
import com.gewuyou.webmvc.spec.jpa.service.JpaCrudServiceSpec
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* CRUD 服务实现的抽象类,提供通用的数据访问操作。
|
* Jpa CRUD 服务实现的抽象类,提供通用的数据访问操作。
|
||||||
*
|
*
|
||||||
* @since 2025-05-29 20:37:27
|
* @since 2025-05-29 20:37:27
|
||||||
* @author gewuyou
|
* @author gewuyou
|
||||||
*/
|
*/
|
||||||
abstract class CrudServiceImplSpec<Entity : Any, Id : Any>(
|
abstract class JpaCrudServiceImplSpec<Entity : Any, Id : Any>(
|
||||||
private val repository: CrudRepositorySpec<Entity, Id>,
|
private val repository: JpaCrudRepositorySpec<Entity, Id>,
|
||||||
) : CrudServiceSpec<Entity, Id> {
|
) : JpaCrudServiceSpec<Entity, Id> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 根据实体的唯一标识符查找实体对象。
|
* 根据实体的唯一标识符查找实体对象。
|
||||||
@ -193,6 +194,7 @@ abstract class CrudServiceImplSpec<Entity : Any, Id : Any>(
|
|||||||
* @param entity 实体对象,表示要标记为删除状态的对象
|
* @param entity 实体对象,表示要标记为删除状态的对象
|
||||||
*/
|
*/
|
||||||
protected abstract fun setDeleted(entity: Entity)
|
protected abstract fun setDeleted(entity: Entity)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 执行软删除操作。
|
* 执行软删除操作。
|
||||||
*
|
*
|
||||||
@ -1,117 +0,0 @@
|
|||||||
# forgeboot-webmvc-spec
|
|
||||||
|
|
||||||
> 🧩 Web 项目通用 CRUD 接口规范模块,封装 Repository 与 Service 层的标准增删改查接口与默认实现,简化重复代码。
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🧩 简介
|
|
||||||
|
|
||||||
`forgeboot-webmvc-spec` 是 ForgeBoot 提供的统一接口规范模块,旨在为常见的 Web 开发提供可复用的 Repository 和 Service 层增删改查基础接口及实现模板。
|
|
||||||
|
|
||||||
通过继承和组合该模块中的接口和基类,可以快速构建具有一致风格的业务组件,提升开发效率、降低重复代码、统一项目结构。
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## ✨ 核心功能
|
|
||||||
|
|
||||||
- ✅ `CrudRepositorySpec<T, ID>`:通用 Repository 接口规范(继承自 `JpaRepository`)
|
|
||||||
- ✅ `CrudServiceSpec<T, ID>`:业务层接口标准化定义
|
|
||||||
- ✅ `CrudServiceImplSpec<T, ID>`:默认 Service 实现(依赖 Repository)
|
|
||||||
- ✅ 泛型支持 Entity 类型与主键类型的自动推导
|
|
||||||
- ✅ 与 DTO 模块 (`forgeboot-webmvc-dto`) 无缝协作
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📦 引入依赖
|
|
||||||
|
|
||||||
使用 Maven:
|
|
||||||
|
|
||||||
```xml
|
|
||||||
<dependency>
|
|
||||||
<groupId>io.github.gewuyou</groupId>
|
|
||||||
<artifactId>forgeboot-webmvc-spec</artifactId>
|
|
||||||
<version>${version}</version>
|
|
||||||
</dependency>
|
|
||||||
```
|
|
||||||
|
|
||||||
使用 Gradle:
|
|
||||||
|
|
||||||
```groovy
|
|
||||||
implementation "io.github.gewuyou:forgeboot-webmvc-spec:${version}"
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🚀 快速开始
|
|
||||||
|
|
||||||
### ✅ 定义实体类
|
|
||||||
|
|
||||||
```kotlin
|
|
||||||
@Entity
|
|
||||||
data class Product(
|
|
||||||
@Id val id: Long,
|
|
||||||
val name: String,
|
|
||||||
val status: Int
|
|
||||||
)
|
|
||||||
```
|
|
||||||
|
|
||||||
### ✅ 创建 Repository 接口
|
|
||||||
|
|
||||||
```kotlin
|
|
||||||
interface ProductRepository : CrudRepositorySpec<Product, Long>
|
|
||||||
```
|
|
||||||
|
|
||||||
### ✅ 创建 Service 接口
|
|
||||||
|
|
||||||
```kotlin
|
|
||||||
interface ProductService : CrudServiceSpec<Product, Long>
|
|
||||||
```
|
|
||||||
|
|
||||||
### ✅ 创建默认实现类
|
|
||||||
|
|
||||||
```kotlin
|
|
||||||
@Service
|
|
||||||
class ProductServiceImpl(
|
|
||||||
override val repository: ProductRepository
|
|
||||||
) : CrudServiceImplSpec<Product, Long>(), ProductService
|
|
||||||
```
|
|
||||||
|
|
||||||
现在你就拥有了以下功能:
|
|
||||||
- 新增:`save(entity)`
|
|
||||||
- 修改:`updateById(id, modifier)`
|
|
||||||
- 删除:`deleteById(id)`
|
|
||||||
- 查询单个:`findById(id)`
|
|
||||||
- 查询全部:`findAll()`
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🧩 扩展方法(默认实现中提供)
|
|
||||||
|
|
||||||
```kotlin
|
|
||||||
fun updateById(id: ID, modifier: (T) -> Unit): Boolean
|
|
||||||
fun existsById(id: ID): Boolean
|
|
||||||
fun deleteById(id: ID): Boolean
|
|
||||||
```
|
|
||||||
|
|
||||||
可自由覆写或组合使用。
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🧠 与其他模块集成建议
|
|
||||||
|
|
||||||
| 模块 | 集成方式说明 |
|
|
||||||
|------------------------|-------------------------------------------|
|
|
||||||
| `forgeboot-webmvc-dto` | 可配合 `PageResult`, `QueryComponent` 返回分页数据 |
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📄 许可协议
|
|
||||||
|
|
||||||
本项目采用 [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0) 开源协议。
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📬 联系作者
|
|
||||||
|
|
||||||
由 [@gewuyou](https://github.com/gewuyou) 维护。
|
|
||||||
|
|
||||||
欢迎提交 Issue 或 PR 改进本模块!
|
|
||||||
@ -75,7 +75,8 @@ include(
|
|||||||
":forgeboot-webmvc:exception-i18n",
|
":forgeboot-webmvc:exception-i18n",
|
||||||
":forgeboot-webmvc:dto",
|
":forgeboot-webmvc:dto",
|
||||||
":forgeboot-webmvc:validation",
|
":forgeboot-webmvc:validation",
|
||||||
":forgeboot-webmvc:spec"
|
":forgeboot-webmvc:spec-core",
|
||||||
|
":forgeboot-webmvc:spec-jpa",
|
||||||
)
|
)
|
||||||
project(":forgeboot-webmvc").name = "forgeboot-webmvc-spring-boot-starter"
|
project(":forgeboot-webmvc").name = "forgeboot-webmvc-spring-boot-starter"
|
||||||
project(":forgeboot-webmvc:version").name = "forgeboot-webmvc-version-spring-boot-starter"
|
project(":forgeboot-webmvc:version").name = "forgeboot-webmvc-version-spring-boot-starter"
|
||||||
@ -84,7 +85,8 @@ project(":forgeboot-webmvc:exception").name = "forgeboot-webmvc-exception-spring
|
|||||||
project(":forgeboot-webmvc:exception-i18n").name = "forgeboot-webmvc-exception-i18n-spring-boot-starter"
|
project(":forgeboot-webmvc:exception-i18n").name = "forgeboot-webmvc-exception-i18n-spring-boot-starter"
|
||||||
project(":forgeboot-webmvc:dto").name = "forgeboot-webmvc-dto"
|
project(":forgeboot-webmvc:dto").name = "forgeboot-webmvc-dto"
|
||||||
project(":forgeboot-webmvc:validation").name = "forgeboot-webmvc-validation"
|
project(":forgeboot-webmvc:validation").name = "forgeboot-webmvc-validation"
|
||||||
project(":forgeboot-webmvc:spec").name = "forgeboot-webmvc-spec"
|
project(":forgeboot-webmvc:spec-core").name = "forgeboot-webmvc-spec-core"
|
||||||
|
project(":forgeboot-webmvc:spec-jpa").name = "forgeboot-webmvc-spec-jpa"
|
||||||
//endregion
|
//endregion
|
||||||
|
|
||||||
//region module core
|
//region module core
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user