7.6 KiB
Spring Boot Service Template
微服务快速开发能力模板,v1.1.0-SNAPSHOT。Java 17, Spring Boot 4.0.0, Spring Cloud 2025.1.0。
GroupId: com.lanyuanxiaoyao,根包: com.lanyuanxiaoyao.service.template。
模块
spring-boot-service-template/ (根 POM, packaging=pom)
├── spring-boot-service-template-common/ (jar — 通用工具)
└── spring-boot-service-template-database/ (jar — JPA 数据库能力)
模块命名规则: spring-boot-service-template-{capability}[-{impl}]
包结构
com.lanyuanxiaoyao.service.template.{module}/
configuration/ # @Configuration(用 configuration 不用 config)
controller/ # REST 控制器 + 接口
entity/ # JPA 实体、Query、GlobalResponse 等数据对象
exception/ # 自定义异常(用 exception 不用 exceptions)
helper/ # 工具类(用 helper 不用 util/utils)
repository/ # Spring Data 仓库
service/ # 业务服务
无独立 DTO/VO 包,DTO 作为 Controller 内部 record。
database 模块
单表 CRUD → REST 接口的快速实现框架。基于 JPA + Fenix + QueryDSL + MapStruct。
实体继承
IdOnlyEntity (id: Long, @SnowflakeId) ← @MappedSuperclass
↑
SimpleEntity (+ createdTime: LocalDateTime, ← @MappedSuperclass
modifiedTime: LocalDateTime)
↑
业务实体 (具体 @Entity)
- ID: Long,雪花算法,字段标
@SnowflakeId(自定义注解) - 时间字段:
@CreatedDate/@LastModifiedDate,JPAAuditingEntityListener自动填充 - 列注释:
@Column(comment = "...") - 物理命名:
PhysicalNamingStrategySnakeCaseImpl(camelCase→snake_case) - 保存: Fenix
saveOrUpdateByNotNullProperties(),自动 INSERT/UPDATE,仅更新非 null 字段
Repository
@NoRepositoryBean
public interface SimpleRepository<E> extends
FenixJpaRepository<E, Long>,
FenixJpaSpecificationExecutor<E>,
ListQueryByExampleExecutor<E>,
ListQuerydslPredicateExecutor<E> {}
业务 Repository 直接继承: interface EmployeeRepository extends SimpleRepository<Employee> {}
无 XML Mapper,无自定义 SQL,查询通过 JPA Criteria / Fenix / QueryDSL 动态构建。
接口组合模式
SimpleService<ENTITY> extends SaveService<ENTITY>, QueryService<ENTITY>, RemoveService<ENTITY>
SimpleController<S, L, D> extends SaveController<S>, QueryController<L, D>, RemoveController
抽象基类: SimpleServiceSupport(Service) / SimpleControllerSupport(Controller),用 *Support 后缀(非 *Impl)。
Controller 子类必须提供三个 mapper 函数: saveItemMapper(), listItemMapper(), detailItemMapper()
CRUD 五步
- 创建实体 — 继承
SimpleEntity - 创建 Repository — 继承
SimpleRepository<Entity> - 创建 Service — 继承
SimpleServiceSupport<Entity> - 创建 DTO — 在 Controller 内定义
SaveItem/ListItem/DetailItemrecord - 创建 Controller — 继承
SimpleControllerSupport<Entity, SaveItem, ListItem, DetailItem>,实现 3 个 mapper
也可用 DatabaseHelper.generateBasicFiles() 自动生成上述脚手架,@RequestMapping 路径由实体名 camelCase→snake_case 推导。DatabaseHelper.generateDDL() 可从实体类生成 DDL SQL。
API 端点
| 操作 | 方法 | 路径 |
|---|---|---|
| 新增/更新 | POST | /save |
| 全部列表 | GET | /list |
| 条件列表 | POST | /list |
| 详情 | GET | /detail/{id} |
| 删除 | GET | /remove/{id} |
统一响应: GlobalResponse<T>(status:Integer, message:String, data:T),成功 status=0,失败 status=500。
- 列表:
data = ListItem<T>(items:Iterable<T>, total:Long) - 详情:
data = DetailItem<T>(item:T)
查询条件
查询对象: Query(Queryable query, List<Sortable> sort, Pageable page)
支持: equal/notEqual/like/notLike/contain/notContain/startWith/endWith/great/less/greatEqual/lessEqual/between/notBetween/inside/notInside/nullEqual/notNullEqual/empty/notEmpty
分页: Pageable(index, size),index 从 1 开始,默认 (1, 10),无排序默认 createdTime DESC
开发规范
命名
| 类别 | 模式 | 示例 |
|---|---|---|
| 实体基类 | *Entity |
IdOnlyEntity, SimpleEntity |
| 业务实体 | 纯名词 | Employee |
| 控制器接口 | *Controller |
SaveController |
| 控制器抽象基类 | *ControllerSupport |
SimpleControllerSupport |
| 服务接口 | *Service |
SaveService |
| 服务抽象基类 | *ServiceSupport |
SimpleServiceSupport |
| 仓库 | *Repository |
EmployeeRepository |
| 工具类 | *Helper |
ObjectHelper |
| 配置类 | *Configuration |
QueryDSLConfiguration |
| 异常 | *Exception |
IdNotFoundException |
| 内部 DTO record | SaveItem/ListItem/DetailItem |
Controller 内部 |
- 接口不加
I前缀 - 方法: 动词开头
save()/list()/detail()/remove();布尔用is/has前缀 - 常量 UPPER_SNAKE_CASE;字段常量用
@FieldNameConstants生成{Class}.Fields.{field} - 泛型: 简单用
T/E,领域用ENTITY/SAVE_ITEM/LIST_ITEM/DETAIL_ITEM
代码风格
- 2 空格缩进,K&R 大括号,不用 Tab
- Import 排序:
java.*→jakarta.*→ 第三方 →com.lanyuanxiaoyao.*,不用通配符 - 积极使用 Java 17 特性:
record(DTO) /var/instanceof模式匹配 / Text Blocks /String.formatted() - JavaDoc 用中文,含
@param/@return/@see,可用<p>/<h3>/<ul>/<pre> - 不写
//行内注释,除非必要
注解
用:
- 实体:
@Getter@Setter@ToString@FieldNameConstants,子类加@ToString(callSuper = true) - 日志:
@Slf4j - 注入:
@RequiredArgsConstructor(access = AccessLevel.PROTECTED)(构造器注入) - 事务: 写
@Transactional(rollbackFor = Throwable.class),读@Transactional(readOnly = true) - 实体基类:
@MappedSuperclass@EntityListeners(AuditingEntityListener.class)
不用:
- 不用
@Valid/@NotNull等校验注解 - 不用 Swagger/OpenAPI 注解
- 不用
@Autowired字段注入 - 不写代码注释(
//),除非必要
异常
继承 RuntimeException,构造器用 String.formatted()。查无数据用 Optional.orElseThrow(() -> new IdNotFoundException(id))。无全局 @ControllerAdvice。
依赖管理
版本集中在根 POM <properties> + <dependencyManagement>,子模块不声明版本。
全局继承: lombok / jspecify:1.0.0
核心: spring-boot-starter-data-jpa / fenix-spring-boot-starter:4.0.0 / querydsl-jpa:7.1 / mapstruct:1.6.3
database 模块注解处理器: lombok → hibernate-jpamodelgen → querydsl-apt(jpa) → jakarta.persistence-api → mapstruct-processor
通用原则
- 文档/注释/commit 用中文,代码标识符用英文
- 不引入新依赖前先复用已有组件,优先 JDK 和 Spring 内置能力
- 构造器注入,不使用
@Autowired字段注入
构建
mvn clean package