1
0
Files
spring-boot-service-template/docs/database-development.md

5.9 KiB
Raw Permalink Blame History

Database 模块开发指南

单表 CRUD → REST 接口快速实现框架。基于 JPA + Fenix + QueryDSL + MapStruct。

架构

Controller (REST) → Service (业务) → Repository (数据访问) → Entity (模型)

组件结构

组件 职责
entity IdOnlyEntity, SimpleEntity 实体基类
entity SnowflakeId, SnowflakeIdGenerator ID 生成
entity Query, GlobalResponse, Page 查询/响应封装
repository SimpleRepository 统一数据访问接口
service SaveService, QueryService, RemoveService 功能接口
service SimpleService, SimpleServiceSupport 组合接口与实现
service QueryParser 查询条件解析
controller SaveController, QueryController, RemoveController REST 接口
controller SimpleController, SimpleControllerSupport 组合接口与实现
helper DatabaseHelper, SnowflakeHelper 工具类
exception *Exception 异常定义

核心设计

实体继承

IdOnlyEntity (id: Long, @SnowflakeId)
    ↑
SimpleEntity (+ createdTime, modifiedTime)
    ↑
业务实体 (@Entity)

实现要点

  • @MappedSuperclass 标记基类
  • @SnowflakeId 触发 SnowflakeIdGenerator 生成 ID
  • @CreatedDate/@LastModifiedDate + AuditingEntityListener 自动填充时间

Repository

@NoRepositoryBean
public interface SimpleRepository<E> extends
    FenixJpaRepository<E, Long>,                    // CRUD + Fenix
    FenixJpaSpecificationExecutor<E>,               // Specification
    ListQueryByExampleExecutor<E>,                  // Example
    ListQuerydslPredicateExecutor<E> {}             // QueryDSL

核心能力

  • saveOrUpdateByNotNullProperties() - 部分字段更新
  • Specification - 动态条件查询
  • QueryDSL - 类型安全查询

Service 接口组合

SaveService<ENTITY>      // save(entity), save(entities)
QueryService<ENTITY>     // detail(id), list(), list(query), count()
RemoveService<ENTITY>    // remove(id), remove(ids)

SimpleService<ENTITY> extends SaveService, QueryService, RemoveService

SimpleServiceSupport 实现

  • 保存Fenix saveOrUpdateByNotNullProperties()
  • 查询JPA Criteria + Specification
  • 删除:deleteBatchByIds()
  • 扩展点:重写 commonPredicates() 添加全局过滤条件

Controller 接口组合

SaveController<SAVE_ITEM>              // POST /save
QueryController<LIST_ITEM, DETAIL_ITEM>  // GET/POST /list, GET /detail/{id}
RemoveController                       // GET /remove/{id}

SimpleController<SAVE_ITEM, LIST_ITEM, DETAIL_ITEM>

SimpleControllerSupport 实现

  • 调用 Service 方法
  • 通过 Mapper 转换 DTO ↔ Entity
  • 封装 GlobalResponse
  • 扩展点:实现 saveItemMapper(), listItemMapper(), detailItemMapper()

查询条件

Query 结构Query(query: Queryable, sort: List<Sortable>, page: Pageable)

QueryParser:抽象类定义解析接口,JpaQueryParser 转换为 JPA Predicate

支持操作

类别 操作
空值 nullEqual, notNullEqual, empty, notEmpty
相等 equal, notEqual
模糊 like, notLike, contain, notContain
前后缀 startWith, endWith, notStartWith, notEndWith
比较 great, less, greatEqual, lessEqual
区间 between, notBetween
集合 inside, notInside

实现JPA CriteriaBuilder 构建,支持多级字段路径(如 user.name自动类型转换枚举、LocalDateTime

响应格式

GlobalResponse<T>(status, message, data)
// status: 0 成功, 500 失败
// 列表: data = ListItem(items, total)
// 详情: data = DetailItem(item)

技术细节

雪花算法

SnowflakeHelper64 位 Long1 位符号 + 41 位时间戳 + 10 位机器 ID + 12 位序列号

SnowflakeIdGenerator:实现 IdentifierGenerator,持久化时调用 SnowflakeHelper.next()

部分更新

Fenix saveOrUpdateByNotNullProperties()

  • 自动判断 INSERT/UPDATE
  • 仅更新非 null 字段

命名策略

PhysicalNamingStrategySnakeCaseImplcamelCase → snake_case

注解处理器

执行顺序lombok → hibernate-jpamodelgen → querydsl-apt → mapstruct-processor

生成getter/setter、JPA 元模型_Entity、QueryDSL Q 类QEntity、MapStruct Mapper

工具类

DatabaseHelper

// 生成 DDL
generateDDL(entityPackages, ddlFilePath, dialect, jdbc, username, password, driver)

// 生成脚手架
generateBasicFiles(entityPackages, projectRootPackage, projectRootPath, override)

SnowflakeHelper

Long id = SnowflakeHelper.next();

扩展指南

软删除

  1. 创建 SoftDeleteEntity extends SimpleEntity,添加 deleted 字段
  2. 重写 commonPredicates() 返回 deleted = false 条件
  3. 覆盖 remove() 改为更新 deleted 字段

多租户

  1. 创建 TenantEntity extends SimpleEntity,添加 tenantId 字段
  2. 重写 commonPredicates() 添加租户过滤
  3. ThreadLocal 或 Spring Security 存储当前租户

审计字段

SimpleEntity 添加 createdBy, modifiedBy,配合 Spring Security 获取当前用户

自定义查询操作符

  1. Query.Queryable 添加字段
  2. QueryParser 添加抽象方法
  3. JpaQueryParser 实现转换为 Predicate

测试

  • H2 内存数据库
  • @DataJpaTest 测试 Repository
  • @WebMvcTest 测试 Controller
  • 测试用例:src/test/java/.../integration/

依赖

核心spring-boot-starter-data-jpa, fenix-spring-boot-starter:4.0.0, querydsl-jpa:7.1, mapstruct:1.6.3

传递spring-boot-service-template-common

注意事项

  • 事务:写操作 @Transactional(rollbackFor = Throwable.class),读操作 @Transactional(readOnly = true)
  • 异常:不使用全局处理器,直接抛出
  • 性能:批量操作使用批量方法
  • 线程安全GlobalResponse 用 record 保证不可变SnowflakeHelper 用原子变量