1
0
Files
spring-boot-service-template/README.md
2026-01-27 10:05:31 +08:00

1612 lines
63 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Spring Boot Service Template
这是一个基于 Spring Boot 的服务模板项目,采用模块化架构设计,旨在为开发者提供标准化的微服务基础结构,简化新项目的搭建过程,提高开发效率。
## 目录
- [1. 项目概述](#1-项目概述)
- [2. 技术架构](#2-技术架构)
- [3. 项目结构](#3-项目结构)
- [4. 核心功能](#4-核心功能)
- [5. 使用指南](#5-使用指南)
- [6. 开发规范](#6-开发规范)
- [7. 项目集成指南](#7-项目集成指南)
- [8. 更新日志](#8-更新日志)
## 1. 项目概述
### 1.1 项目简介
Spring Boot Service Template 是一个标准化的微服务基础结构模板,专为 Java 开发者和微服务架构设计者打造。该项目采用模块化架构设计,提供了一套完整的 CRUD 操作框架支持多种数据库访问方式JPA、Easy Query、Xbatis通过泛型支持不同类型的数据转换大大减少了重复代码的编写。
该模板内置了完善的实体审计机制,自动维护实体的创建时间和修改时间。同时,提供了强大的查询功能,支持多种条件查询、分页和排序功能。
**当前版本**1.1.0-SNAPSHOT
**核心版本依赖**
- Java 17
- Spring Boot 4.0.0
- Spring Cloud 2025.1.0
- Hibernate 7.1.8.Final
- QueryDSL 7.1
- Easy Query 3.1.68
- Xbatis 1.9.7-spring-boot4
Spring Boot Service Template 是一个标准化的微服务基础结构模板,专为 Java 开发者和微服务架构设计者打造。该项目采用模块化架构设计,提供了一套完整的 CRUD 操作框架支持多种数据库访问方式JPA、Easy Query、Xbatis通过泛型支持不同类型的数据转换大大减少了重复代码的编写。
该模板内置了完善的实体审计机制,自动维护实体的创建时间和修改时间。同时,提供了强大的查询功能,支持多种条件查询、分页和排序功能。
### 1.2 项目目标
提供统一的服务模板,简化新项目的搭建过程,提高开发效率。通过封装通用的业务逻辑,让开发者能够专注于核心业务功能的实现。
### 1.3 核心特性
- **模块化架构**:采用多模块设计,通用功能与数据库操作分离,便于按需引入
- **标准化的项目结构**:遵循业界最佳实践的目录结构和代码组织方式
- **多数据库支持**:支持 JPA、Easy Query、Xbatis 三种数据库访问方式,可根据项目需求灵活选择
- **简化依赖管理和构建流程**:基于 Maven 的依赖管理,清晰的构建配置,统一的编译插件配置
- **支持快速构建和部署微服务**:提供完整的微服务基础组件
- **泛型支持**:通过泛型实现不同类型间的数据转换,减少重复代码
- **完善的审计机制**JPA 模块):自动维护实体的创建时间和修改时间,通过 Spring Data JPA 审计功能实现
- **强大的查询功能**:支持 21 种查询条件类型,包括空值、相等、模糊匹配、范围、集合、区间等
- **分页和排序支持**:内置分页查询和排序功能,支持多字段排序
- **灵活的扩展机制**:易于定制和扩展的架构设计,支持自定义查询条件和 Mapper 方法
- **统一的响应格式**:标准化的 API 响应结构,提供多种工厂方法简化响应创建
- **雪花 ID 生成器**:支持分布式环境下的唯一 ID 生成,基于 Snowflake 算法
- **逻辑删除支持**EQ 和 Xbatis 模块):通过注解实现逻辑删除功能,避免物理删除数据
- **查询解析器模板**:采用模板方法模式,统一查询条件解析逻辑,各数据库实现模块提供具体实现
- **完整的异常处理**:提供业务异常类,支持类型检查异常处理
### 1.4 适用场景
适用于需要快速搭建 Spring Boot 微服务的项目,特别是那些需要大量 CRUD 操作的业务系统。支持三种数据库访问方式,可根据项目需求灵活选择:
- **JPA 模块**:适合传统的 Spring Data JPA 项目,提供完整的 JPA 功能
- **Easy Query 模块**:适合需要类型安全查询的项目,提供强大的查询构建能力
- **Xbatis 模块**:适合需要 MyBatis 灵活性的项目,提供增强的 MyBatis 功能
## 2. 技术架构
### 2.1 技术选型
#### 2.1.1 后端技术栈
- Java 17
- Spring Boot 4.0.0
- Spring Cloud 2025.1.0
- Lombok
- MapStruct 1.6.3
- MapStruct Plus 1.5.0
- Hutool 5.8.43
- JSpecify 1.0.0
#### 2.1.2 数据库技术栈
**JPA 模块**
- Spring Data JPA
- Hibernate 7.1.8.Final
- QueryDSL 7.1
- Fenix 4.0.0
- Hibernate JPA Model Generator 7.1.8.Final
**Easy Query 模块**
- Easy Query 3.1.68
- SQL Processor 3.1.68
**Xbatis 模块**
- Xbatis 1.9.7-spring-boot4
- 基于增强的 MyBatis
**通用组件**
- P6spy Spring Boot Starter 2.0.0SQL 日志)
- Datasource Proxy Spring Boot Starter 2.0.0(数据源代理)
#### 2.1.3 核心框架
- Spring Boot 作为核心框架,提供自动配置和快速开发能力
- Spring Data JPA 用于数据访问简化数据库操作JPA 模块)
- QueryDSL 用于类型安全的查询构建避免运行时错误JPA 模块)
- Fenix 用于复杂动态查询提供更灵活的查询能力JPA 模块)
- Easy Query 用于类型安全的查询构建和灵活的数据访问EQ 模块)
- Xbatis 用于增强的 MyBatis 数据访问Xbatis 模块)
- Lombok 减少样板代码,提高开发效率
- MapStruct 用于对象映射,简化数据转换
- JSpecify 提供空安全注解支持
#### 2.1.4 数据库技术
- H2 Database (测试环境)
### 2.2 架构设计
#### 2.2.1 整体架构图
```
┌─────────────────────────────────────┐
│ Controller Layer │
│ (处理HTTP请求数据转换与响应) │
├─────────────────────────────────────┤
│ Service Layer │
│ (业务逻辑处理,事务管理) │
├─────────────────────────────────────┤
│ Repository/Mapper Layer │
│ (数据访问,数据库交互) │
├─────────────────────────────────────┤
│ Entity Layer │
│ (数据模型定义,实体映射) │
└─────────────────────────────────────┘
```
#### 2.2.2 模块划分
项目采用模块化架构,主要包含以下模块:
**通用模块**
- spring-boot-service-template-common通用工具类模块提供对象操作等基础功能
**数据库通用模块**
- spring-boot-service-template-database-common数据库通用功能模块定义统一的 Controller、Service 接口和实体类
- spring-boot-service-template-database-common-test数据库通用测试模块提供测试基类和配置
**数据库实现模块**
- spring-boot-service-template-database-jpaJPA 实现模块,基于 Spring Data JPA
- spring-boot-service-template-database-eqEasy Query 实现模块,基于 Easy Query
- spring-boot-service-template-database-xbatisXbatis 实现模块,基于增强的 MyBatis
#### 2.2.3 设计模式
- **模板方法模式**:通过 SimpleControllerSupport 和 SimpleServiceSupport 抽象类定义通用操作流程,子类实现 Mapper 方法完成数据转换
- **策略模式**:通过 Function 接口实现 saveItemMapper、listItemMapper、detailItemMapper 等数据转换策略
- **仓储模式**:通过 SimpleRepository、MybatisBasicMapper 等接口封装数据访问逻辑,提供统一的数据操作接口
- **工厂模式**:通过 GlobalResponse 提供多种工厂方法responseSuccess、responseError、responseListData 等)创建响应对象
- **模板方法模式(查询解析)**:通过 QueryParser 抽象类定义查询条件解析流程各实现模块JpaQueryParser、EqQueryParser、XBatisQueryParser实现具体的查询条件构建逻辑
## 3. 项目结构
### 3.1 目录结构说明
```
spring-boot-service-template/
├── spring-boot-service-template-common/ # 通用工具类模块
│ └── src/main/java/com/lanyuanxiaoyao/service/template/common/
│ └── helper/
│ └── ObjectHelper.java # 对象工具类
├── spring-boot-service-template-database/ # 数据库模块目录
│ ├── spring-boot-service-template-database-common/ # 数据库通用模块
│ │ └── src/main/java/com/lanyuanxiaoyao/service/template/database/common/
│ │ ├── controller/ # 控制器接口定义
│ │ │ ├── SimpleController.java
│ │ │ ├── SaveController.java
│ │ │ ├── QueryController.java
│ │ │ └── RemoveController.java
│ │ ├── service/ # 服务接口定义
│ │ │ ├── SimpleService.java
│ │ │ ├── SaveService.java
│ │ │ ├── QueryService.java
│ │ │ ├── RemoveService.java
│ │ │ └── QueryParser.java # 查询解析器
│ │ ├── entity/ # 通用实体类
│ │ │ ├── GlobalResponse.java # 统一响应格式
│ │ │ ├── Query.java # 查询条件封装
│ │ │ └── Page.java # 分页结果封装
│ │ ├── exception/ # 异常定义
│ │ │ ├── IdNotFoundException.java
│ │ │ ├── NotCollectionException.java
│ │ │ ├── NotComparableException.java
│ │ │ └── NotStringException.java
│ │ └── helper/ # 辅助类
│ │ └── SnowflakeHelper.java # 雪花ID生成器
│ │
│ ├── spring-boot-service-template-database-common-test/ # 数据库通用测试模块
│ │ └── src/main/java/com/lanyuanxiaoyao/service/template/database/common/test/
│ │ └── AbstractTestApplication.java # 测试应用基类
│ │
│ ├── spring-boot-service-template-database-jpa/ # JPA 实现模块
│ │ ├── src/main/java/com/lanyuanxiaoyao/service/template/database/jpa/
│ │ │ ├── controller/
│ │ │ │ └── SimpleControllerSupport.java # JPA 控制器实现
│ │ │ ├── service/
│ │ │ │ └── SimpleServiceSupport.java # JPA 服务实现
│ │ │ ├── repository/
│ │ │ │ └── SimpleRepository.java # JPA 仓储接口
│ │ │ ├── entity/
│ │ │ │ ├── IdOnlyEntity.java # 仅包含 ID 的实体
│ │ │ │ ├── SimpleEntity.java # 包含基础字段的实体
│ │ │ │ ├── SnowflakeId.java # 雪花 ID 注解
│ │ │ │ └── SnowflakeIdGenerator.java # 雪花 ID 生成器
│ │ │ └── helper/
│ │ │ └── DatabaseHelper.java # 数据库辅助类
│ │ └── src/test/java/... # 测试用例
│ │
│ ├── spring-boot-service-template-database-eq/ # Easy Query 实现模块
│ │ ├── src/main/java/com/lanyuanxiaoyao/service/template/database/eq/
│ │ │ ├── controller/
│ │ │ │ └── SimpleControllerSupport.java # EQ 控制器实现
│ │ │ ├── service/
│ │ │ │ └── SimpleServiceSupport.java # EQ 服务实现
│ │ │ └── entity/
│ │ │ ├── IdOnlyEntity.java # 仅包含 ID 的实体
│ │ │ ├── LogicDeleteEntity.java # 逻辑删除实体
│ │ │ ├── SimpleEntity.java # 包含基础字段的实体
│ │ │ └── SnowflakeIdGenerator.java # 雪花 ID 生成器
│ │ └── src/test/java/... # 测试用例
│ │
│ └── spring-boot-service-template-database-xbatis/ # Xbatis 实现模块
│ ├── src/main/java/com/lanyuanxiaoyao/service/template/database/xbatis/
│ │ ├── controller/
│ │ │ └── SimpleControllerSupport.java # Xbatis 控制器实现
│ │ ├── service/
│ │ │ └── SimpleServiceSupport.java # Xbatis 服务实现
│ │ ├── mapper/
│ │ │ └── MybatisBasicMapper.java # MyBatis 基础 Mapper
│ │ ├── entity/
│ │ │ ├── IdOnlyEntity.java # 仅包含 ID 的实体
│ │ │ ├── LogicDeleteEntity.java # 逻辑删除实体
│ │ │ ├── SimpleEntity.java # 包含基础字段的实体
│ │ │ └── SnowflakeIdGenerator.java # 雪花 ID 生成器
│ │ └── configuration/
│ │ └── MybatisConfiguration.java # MyBatis 配置
│ └── src/test/java/... # 测试用例
├── pom.xml # 父 POM 文件
└── README.md # 项目文档
```
### 3.2 核心模块介绍
#### 3.2.1 common 模块
提供通用的工具类,主要包含:
- [ObjectHelper](spring-boot-service-template-common/src/main/java/com/lanyuanxiaoyao/service/template/common/helper/ObjectHelper.java):对象工具类,提供对象空值判断、类型判断等常用功能
#### 3.2.2 database-common 模块
定义数据库操作的通用接口和实体类,主要包含:
- **controller 包**
- [SimpleController](spring-boot-service-template-database/spring-boot-service-template-database-common/src/main/java/com/lanyuanxiaoyao/service/template/database/common/controller/SimpleController.java):定义基础 CRUD 控制器接口
- [SaveController](spring-boot-service-template-database/spring-boot-service-template-database-common/src/main/java/com/lanyuanxiaoyao/service/template/database/common/controller/SaveController.java):保存操作接口,提供 save 方法
- [QueryController](spring-boot-service-template-database/spring-boot-service-template-database-common/src/main/java/com/lanyuanxiaoyao/service/template/database/common/controller/QueryController.java):查询操作接口,提供 list 和 detail 方法
- [RemoveController](spring-boot-service-template-database/spring-boot-service-template-database-common/src/main/java/com/lanyuanxiaoyao/service/template/database/common/controller/RemoveController.java):删除操作接口,提供 remove 方法
- **service 包**
- [SimpleService](spring-boot-service-template-database/spring-boot-service-template-database-common/src/main/java/com/lanyuanxiaoyao/service/template/database/common/service/SimpleService.java):定义基础服务接口,整合 SaveService、QueryService 和 RemoveService
- [SaveService](spring-boot-service-template-database/spring-boot-service-template-database-common/src/main/java/com/lanyuanxiaoyao/service/template/database/common/service/SaveService.java):保存服务接口,支持单条和批量保存
- [QueryService](spring-boot-service-template-database/spring-boot-service-template-database-common/src/main/java/com/lanyuanxiaoyao/service/template/database/common/service/QueryService.java):查询服务接口,支持详情查询、列表查询、分页查询和统计
- [RemoveService](spring-boot-service-template-database/spring-boot-service-template-database-common/src/main/java/com/lanyuanxiaoyao/service/template/database/common/service/RemoveService.java):删除服务接口,支持单条和批量删除
- [QueryParser](spring-boot-service-template-database/spring-boot-service-template-database-common/src/main/java/com/lanyuanxiaoyao/service/template/database/common/service/QueryParser.java):查询条件解析器抽象类,模板方法模式,支持 21 种查询条件类型
- **entity 包**
- [GlobalResponse](spring-boot-service-template-database/spring-boot-service-template-database-common/src/main/java/com/lanyuanxiaoyao/service/template/database/common/entity/GlobalResponse.java):统一 API 响应封装类提供多种工厂方法responseSuccess、responseError、responseListData、responseDetailData 等)
- [Query](spring-boot-service-template-database/spring-boot-service-template-database-common/src/main/java/com/lanyuanxiaoyao/service/template/database/common/entity/Query.java):查询条件封装类,包含 Queryable、Sortable 和 Pageable 三个嵌套 record
- [Page](spring-boot-service-template-database/spring-boot-service-template-database-common/src/main/java/com/lanyuanxiaoyao/service/template/database/common/entity/Page.java):分页结果封装类,包含 items 列表和 total 总数
- **exception 包**
- [IdNotFoundException](spring-boot-service-template-database/spring-boot-service-template-database-common/src/main/java/com/lanyuanxiaoyao/service/template/database/common/exception/IdNotFoundException.java)ID 不存在异常
- [NotCollectionException](spring-boot-service-template-database/spring-boot-service-template-database-common/src/main/java/com/lanyuanxiaoyao/service/template/database/common/exception/NotCollectionException.java):非集合类型异常
- [NotComparableException](spring-boot-service-template-database/spring-boot-service-template-database-common/src/main/java/com/lanyuanxiaoyao/service/template/database/common/exception/NotComparableException.java):不可比较异常
- [NotStringException](spring-boot-service-template-database/spring-boot-service-template-database-common/src/main/java/com/lanyuanxiaoyao/service/template/database/common/exception/NotStringException.java):非字符串类型异常
- **helper 包**
- [SnowflakeHelper](spring-boot-service-template-database/spring-boot-service-template-database-common/src/main/java/com/lanyuanxiaoyao/service/template/database/common/helper/SnowflakeHelper.java):雪花 ID 生成器,提供分布式唯一 ID 生成能力
#### 3.2.3 database-jpa 模块
基于 Spring Data JPA 的实现,主要包含:
- [SimpleControllerSupport](spring-boot-service-template-database/spring-boot-service-template-database-jpa/src/main/java/com/lanyuanxiaoyao/service/template/database/jpa/controller/SimpleControllerSupport.java)JPA 控制器实现,通过泛型支持数据转换
- [SimpleServiceSupport](spring-boot-service-template-database/spring-boot-service-template-database-jpa/src/main/java/com/lanyuanxiaoyao/service/template/database/jpa/service/SimpleServiceSupport.java)JPA 服务实现,使用 JPA Criteria API 构建查询,包含内部类 JpaQueryParser
- [SimpleRepository](spring-boot-service-template-database/spring-boot-service-template-database-jpa/src/main/java/com/lanyuanxiaoyao/service/template/database/jpa/repository/SimpleRepository.java)JPA 仓储接口,整合 FenixJpaRepository、FenixJpaSpecificationExecutor、ListQueryByExampleExecutor 和 ListQuerydslPredicateExecutor 四种数据访问能力
- [SimpleEntity](spring-boot-service-template-database/spring-boot-service-template-database-jpa/src/main/java/com/lanyuanxiaoyao/service/template/database/jpa/entity/SimpleEntity.java):包含 ID、创建时间和修改时间的实体基类
- [IdOnlyEntity](spring-boot-service-template-database/spring-boot-service-template-database-jpa/src/main/java/com/lanyuanxiaoyao/service/template/database/jpa/entity/IdOnlyEntity.java):仅包含 ID 的基础实体
- [SnowflakeId](spring-boot-service-template-database/spring-boot-service-template-database-jpa/src/main/java/com/lanyuanxiaoyao/service/template/database/jpa/entity/SnowflakeId.java):自定义 Hibernate ID 生成器注解
- [SnowflakeIdGenerator](spring-boot-service-template-database/spring-boot-service-template-database-jpa/src/main/java/com/lanyuanxiaoyao/service/template/database/jpa/entity/SnowflakeIdGenerator.java)Hibernate ID 生成器实现类,调用 SnowflakeHelper 生成 ID
#### 3.2.4 database-eq 模块
基于 Easy Query 的实现,主要包含:
- [SimpleControllerSupport](spring-boot-service-template-database/spring-boot-service-template-database-eq/src/main/java/com/lanyuanxiaoyao/service/template/database/eq/controller/SimpleControllerSupport.java)Easy Query 控制器实现,要求实体类实现 ProxyEntityAvailable 接口
- [SimpleServiceSupport](spring-boot-service-template-database/spring-boot-service-template-database-eq/src/main/java/com/lanyuanxiaoyao/service/template/database/eq/service/SimpleServiceSupport.java)Easy Query 服务实现,使用 Easy Query API 构建查询,包含内部类 EqQueryParser
- [SimpleEntity](spring-boot-service-template-database/spring-boot-service-template-database-eq/src/main/java/com/lanyuanxiaoyao/service/template/database/eq/entity/SimpleEntity.java):包含基础字段的实体类
- [LogicDeleteEntity](spring-boot-service-template-database/spring-boot-service-template-database-eq/src/main/java/com/lanyuanxiaoyao/service/template/database/eq/entity/LogicDeleteEntity.java):逻辑删除实体,使用 @LogicDelete 注解
#### 3.2.5 database-xbatis 模块
基于 Xbatis 的实现,主要包含:
- [SimpleControllerSupport](spring-boot-service-template-database/spring-boot-service-template-database-xbatis/src/main/java/com/lanyuanxiaoyao/service/template/database/xbatis/controller/SimpleControllerSupport.java)Xbatis 控制器实现
- [SimpleServiceSupport](spring-boot-service-template-database/spring-boot-service-template-database-xbatis/src/main/java/com/lanyuanxiaoyao/service/template/database/xbatis/service/SimpleServiceSupport.java)Xbatis 服务实现,使用 Xbatis API 构建查询,包含内部类 XBatisQueryParser
- [MybatisBasicMapper](spring-boot-service-template-database/spring-boot-service-template-database-xbatis/src/main/java/com/lanyuanxiaoyao/service/template/database/xbatis/mapper/MybatisBasicMapper.java)Xbatis 基础 Mapper继承 BasicMapper 提供基本 CRUD 操作
- [SimpleEntity](spring-boot-service-template-database/spring-boot-service-template-database-xbatis/src/main/java/com/lanyuanxiaoyao/service/template/database/xbatis/entity/SimpleEntity.java):包含基础字段的实体类
- [LogicDeleteEntity](spring-boot-service-template-database/spring-boot-service-template-database-xbatis/src/main/java/com/lanyuanxiaoyao/service/template/database/xbatis/entity/LogicDeleteEntity.java):逻辑删除实体,使用 @LogicDelete@LogicDeleteTime 注解
### 3.3 测试模块结构
每个数据库实现模块都包含完整的测试用例,通过实际的业务实体(如 Employee、Company、Report演示如何使用模板。
**database-common-test 模块**
- [AbstractTestApplication](spring-boot-service-template-database/spring-boot-service-template-database-common-test/src/main/java/com/lanyuanxiaoyao/service/template/database/common/test/AbstractTestApplication.java):测试基类,提供完整的 CRUD 测试流程
- 提供测试用的 HTTP 客户端RestTemplate
- 提供 JSON 序列化工具ObjectMapper
- 提供随机数据生成方法
- 提供 testCrud() 方法,完整测试保存、查询、分页、条件查询、删除等操作
- 提供断言方法,验证返回结果
## 4. 核心功能
### 4.1 基础 CRUD 操作
#### 4.1.1 创建 (Create)
支持通过 POST 请求创建实体对象。通过 save 接口实现,接收 SAVE_ITEM 类型的参数,通过 Mapper 转换为实体对象后保存。
#### 4.1.2 查询 (Retrieve)
支持多种查询方式:
- 列表查询:获取所有实体对象
- 条件查询:根据指定条件查询实体对象
- 详情查询:根据 ID 获取单个实体对象
#### 4.1.3 更新 (Update)
支持通过 POST 请求更新实体对象。通过 save 接口实现,当传入包含 ID 的对象时执行更新操作。
#### 4.1.4 删除 (Delete)
支持通过 GET 请求删除实体对象。通过 remove 接口实现,根据 ID 删除指定实体。
### 4.2 查询功能详解
#### 4.2.1 简单查询
支持基于 ID 的简单查询,通过 detail 接口实现。
#### 4.2.2 条件查询
支持基于多种条件的复杂查询,通过 list 接口实现,支持以下查询条件:
- nullEqual: 字段值为 null 的条件
- notNullEqual: 字段值不为 null 的条件
- empty: 字段值为空的条件
- notEmpty: 字段值不为空的条件
- equal: 字段值相等的条件
- notEqual: 字段值不相等的条件
- like: 字段值模糊匹配的条件
- notLike: 字段值不模糊匹配的条件
- contain: 字段包含指定字符串的条件
- notContain: 字段不包含指定字符串的条件
- startWith: 字段以指定字符串开头的条件
- notStartWith: 字段不以指定字符串开头的条件
- endWith: 字段以指定字符串结尾的条件
- notEndWith: 字段不以指定字符串结尾的条件
- great: 字段值大于的条件
- less: 字段值小于的条件
- greatEqual: 字段值大于等于的条件
- lessEqual: 字段值小于等于的条件
- inside: 字段值在指定范围内的条件
- notInside: 字段值不在指定范围内的条件
- between: 字段值在指定区间内的条件
- notBetween: 字段值不在指定区间内的条件
#### 4.2.3 分页查询
支持分页查询功能,通过 page 配置实现分页参数设置。
#### 4.2.4 排序查询
支持排序查询功能,通过 sort 配置实现排序参数设置。
### 4.3 数据实体设计
#### 4.3.1 基础实体类
定义通用的实体基类,包括 IdOnlyEntity 和 SimpleEntity。
**IdOnlyEntity**
- 仅包含 ID 字段,使用 @SnowflakeId 注解自动生成雪花 ID
- 使用 @EntityListeners(AuditingEntityListener.class) 启用审计功能
**SimpleEntity**JPA 模块):
- 继承 IdOnlyEntity
- 添加 createdTime 字段(@CreatedDate 注解,自动设置创建时间)
- 添加 modifiedTime 字段(@LastModifiedDate 注解,自动更新修改时间)
**SimpleEntity**EQ/Xbatis 模块):
- 继承 IdOnlyEntity
- 作为实体基类,需要根据业务需求添加审计字段
**LogicDeleteEntity**EQ/Xbatis 模块):
- 继承 IdOnlyEntity
- 添加 deleted 字段(@LogicDelete 注解,实现逻辑删除)
- Xbatis 模块额外添加 deletedTime 字段(@LogicDeleteTime 注解,记录删除时间)
#### 4.3.2 审计字段
包含创建时间 (createdTime) 和修改时间 (modifiedTime) 等审计字段,通过 Spring Data JPA 的审计功能自动维护JPA 模块)。
#### 4.3.3 实体关系
支持常见的实体关系映射,如一对一、一对多、多对多等。
#### 4.3.4 雪花 ID 生成器
支持分布式环境下的唯一 ID 生成,通过以下方式实现:
- **SnowflakeHelper**:雪花 ID 生成工具类,提供 `next()` 方法生成唯一 ID
- **@SnowflakeId 注解**JPA 模块):自定义 Hibernate ID 生成器注解,标记需要使用雪花 ID 的字段
- **SnowflakeIdGenerator**JPA 模块Hibernate IdentifierGenerator 实现,调用 SnowflakeHelper 生成 ID
#### 4.3.5 逻辑删除
支持逻辑删除功能,通过 LogicDeleteEntity 实现EQ 和 Xbatis 模块):
- **EQ 模块**:使用 @LogicDelete 注解标记 deleted 字段
- **Xbatis 模块**:使用 @LogicDelete@LogicDeleteTime 注解标记 deleted 和 deletedTime 字段
#### 4.3.6 查询解析器
QueryParser 是查询条件解析的抽象基类,采用模板方法模式,定义了 21 种查询条件的解析方法:
- **空值条件**nullEqual、notNullEqual、empty、notEmpty
- **相等条件**equal、notEqual
- **模糊匹配**like、notLike、contain、notContain
- **前后缀匹配**startWith、notStartWith、endWith、notEndWith
- **范围条件**great、less、greatEqual、lessEqual
- **集合条件**inside、notInside
- **区间条件**between、notBetween
各数据库实现模块通过继承 QueryParser 实现具体的查询条件构建逻辑:
- **JpaQueryParser**JPA 模块):将查询条件转换为 JPA Criteria API 的 Predicate
- **EqQueryParser**EQ 模块):将查询条件转换为 Easy Query 的代理 API 调用
- **XBatisQueryParser**Xbatis 模块):将查询条件转换为 Xbatis 的 Where 条件
### 4.4 统一响应格式
提供统一的 API 响应格式,包含以下字段:
- status: 响应状态码0 表示成功500 表示错误)
- message: 响应消息
- data: 响应数据
支持多种响应类型:
- 成功响应(无数据)
- 成功响应(带数据)
- 分页列表响应(包含 items 和 total
- 详情响应
- 错误响应
**GlobalResponse 提供的工厂方法**
- `responseSuccess()`:返回默认成功响应
- `responseSuccess(String message)`:返回指定消息的成功响应
- `responseSuccess(E data)`:返回带数据的成功响应
- `responseSuccess(String message, E data)`:返回指定消息和数据的成功响应
- `responseError()`:返回默认错误响应
- `responseError(String message)`:返回指定消息的错误响应
- `responseMapData(Map data)`:返回 Map 格式数据的成功响应
- `responseMapData(String key, Object value)`:返回单个键值对的成功响应
- `responseListData()`:返回空列表的成功响应
- `responseListData(Iterable data, Integer/Long total)`:返回列表数据的成功响应
- `responseDetailData(Object data)`:返回详情数据的成功响应
## 5. 使用指南
### 5.1 环境准备
#### 5.1.1 JDK 安装
需要安装 JDK 17 或更高版本。
#### 5.1.2 Maven 配置
需要配置 Maven 3.x 环境。
### 5.2 项目构建
#### 5.2.1 依赖管理
通过 Maven 管理项目依赖。
#### 5.2.2 编译打包
使用 `mvn clean package` 命令编译打包项目。
### 5.3 运行部署
#### 5.3.1 本地运行
可以使用 `mvn spring-boot:run` 命令运行项目。
#### 5.3.2 生产部署
可通过生成的 JAR 文件直接运行或部署到服务器,使用命令:
`java -jar target/spring-boot-service-template-1.1.0-SNAPSHOT.jar`
## 6. 开发规范
### 6.1 代码规范
遵循 Java 标准编码规范和 Spring Boot 最佳实践。
### 6.2 接口规范
RESTful API 设计规范,统一的响应格式。
### 6.3 注释规范
遵循标准的 JavaDoc 格式编写注释,详细说明类、方法、参数和返回值的含义。
### 6.4 异常处理
统一异常处理机制,提供友好的错误信息。
## 7. 项目集成指南
本章节详细介绍如何在现有项目中集成 Spring Boot Service Template 的能力。
### 7.1 集成方式
通过 Maven 依赖引入(推荐)
### 7.2 选择数据库实现方式
项目提供三种数据库实现方式,根据您的需求选择:
- **JPA 模块**:适合传统的 Spring Data JPA 项目
- **Easy Query 模块**:适合需要类型安全查询的项目
- **Xbatis 模块**:适合需要 MyBatis 灵活性的项目
### 7.3 Maven 依赖引入方式
#### 7.3.1 添加基础依赖
在您的项目 pom.xml 文件中添加以下依赖:
```xml
<dependency>
<groupId>com.lanyuanxiaoyao</groupId>
<artifactId>spring-boot-service-template-common</artifactId>
<version>1.1.0-SNAPSHOT</version>
</dependency>
```
#### 7.3.2 添加数据库实现依赖
根据您选择的数据库实现方式,添加对应的依赖:
**JPA 实现**
```xml
<dependency>
<groupId>com.lanyuanxiaoyao</groupId>
<artifactId>spring-boot-service-template-database-jpa</artifactId>
<version>1.1.0-SNAPSHOT</version>
</dependency>
```
**Easy Query 实现**
```xml
<dependency>
<groupId>com.lanyuanxiaoyao</groupId>
<artifactId>spring-boot-service-template-database-eq</artifactId>
<version>1.1.0-SNAPSHOT</version>
</dependency>
```
**Xbatis 实现**
```xml
<dependency>
<groupId>com.lanyuanxiaoyao</groupId>
<artifactId>spring-boot-service-template-database-xbatis</artifactId>
<version>1.1.0-SNAPSHOT</version>
</dependency>
```
#### 7.3.3 配置依赖管理
确保您的项目中包含以下依赖管理配置:
```xml
<dependencyManagement>
<dependencies>
<!-- spring boot 相关依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>4.0.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>2025.1.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
```
#### 7.3.4 配置编译插件
确保您的项目中包含以下编译插件配置:
**JPA 模块编译插件**
```xml
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.14.1</version>
<configuration>
<annotationProcessorPaths>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</path>
<path>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-jpamodelgen</artifactId>
<version>7.1.8.Final</version>
</path>
<path>
<groupId>io.github.openfeign.querydsl</groupId>
<artifactId>querydsl-apt</artifactId>
<version>7.1</version>
<classifier>jpa</classifier>
</path>
<path>
<groupId>jakarta.persistence</groupId>
<artifactId>jakarta.persistence-api</artifactId>
<version>3.2.0</version>
</path>
</annotationProcessorPaths>
<compilerArgs>
<arg>-Aquerydsl.entityAccessors=true</arg>
<arg>-Aquerydsl.createDefaultVariable=true</arg>
</compilerArgs>
</configuration>
</plugin>
</plugins>
</build>
```
**Easy Query 模块编译插件**
```xml
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.14.1</version>
<configuration>
<annotationProcessorPaths>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</path>
<path>
<groupId>com.easy-query</groupId>
<artifactId>sql-processor</artifactId>
<version>3.1.68</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
</plugins>
</build>
```
**Xbatis 模块编译插件**
```xml
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.14.1</version>
<configuration>
<annotationProcessorPaths>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
</plugins>
</build>
```
### 7.4 创建业务模块
创建业务模块的步骤如下(以 JPA 模块为例):
#### 7.4.1 创建实体类
创建实体类并继承 SimpleEntity
```java
import com.lanyuanxiaoyao.service.template.database.jpa.entity.SimpleEntity;
import jakarta.persistence.Entity;
import jakarta.persistence.Table;
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.FieldNameConstants;
@Getter
@Setter
@FieldNameConstants
@Entity
@Table(name = "employee")
public class Employee extends SimpleEntity {
private String name;
private Integer age;
// 其他字段和方法
}
```
#### 7.4.2 创建仓储接口
创建仓储接口并继承 SimpleRepository
```java
import com.lanyuanxiaoyao.service.template.database.jpa.repository.SimpleRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface EmployeeRepository extends SimpleRepository<Employee> {
// 自定义查询方法
}
```
#### 7.4.3 创建服务类
创建服务类并继承 SimpleServiceSupport
```java
import com.lanyuanxiaoyao.service.template.database.jpa.service.SimpleServiceSupport;
import org.springframework.stereotype.Service;
@Service
public class EmployeeService extends SimpleServiceSupport<Employee> {
public EmployeeService(EmployeeRepository repository) {
super(repository);
}
// 自定义业务方法
}
```
#### 7.4.4 创建控制器类
创建控制器类并继承 SimpleControllerSupport
```java
import com.lanyuanxiaoyao.service.template.database.jpa.controller.SimpleControllerSupport;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("employee")
public class EmployeeController extends SimpleControllerSupport<Employee, EmployeeSaveItem, EmployeeListItem, EmployeeDetailItem> {
public EmployeeController(EmployeeService service) {
super(service);
}
@Override
protected Function<EmployeeSaveItem, Employee> saveItemMapper() {
// 实现保存项转换逻辑
return item -> {
Employee employee = new Employee();
employee.setId(item.getId());
employee.setName(item.getName());
employee.setAge(item.getAge());
return employee;
};
}
@Override
protected Function<Employee, EmployeeListItem> listItemMapper() {
// 实现列表项转换逻辑
return employee -> {
EmployeeListItem item = new EmployeeListItem();
item.setId(employee.getId());
item.setName(employee.getName());
item.setAge(employee.getAge());
return item;
};
}
@Override
protected Function<Employee, EmployeeDetailItem> detailItemMapper() {
// 实现详情项转换逻辑
return employee -> {
EmployeeDetailItem item = new EmployeeDetailItem();
item.setId(employee.getId());
item.setName(employee.getName());
item.setAge(employee.getAge());
item.setCreatedTime(employee.getCreatedTime());
item.setModifiedTime(employee.getModifiedTime());
return item;
};
}
}
```
#### 7.4.5 创建数据传输对象
创建用于数据传输的对象:
```java
// 保存项
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.FieldNameConstants;
@Getter
@Setter
@FieldNameConstants
public class EmployeeSaveItem {
private Long id;
private String name;
private Integer age;
// getter和setter方法
}
// 列表项
@Getter
@Setter
@FieldNameConstants
public class EmployeeListItem {
private Long id;
private String name;
private Integer age;
// getter和setter方法
}
// 详情项
@Getter
@Setter
@FieldNameConstants
public class EmployeeDetailItem {
private Long id;
private String name;
private Integer age;
private LocalDateTime createdTime;
private LocalDateTime modifiedTime;
// getter和setter方法
}
```
### 7.5 配置启用 JPA 审计JPA 模块)
在您的主应用类上添加 @EnableJpaAuditing 注解以启用 JPA 审计功能:
```java
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
@SpringBootApplication
@EnableJpaAuditing
public class YourApplication {
public static void main(String[] args) {
SpringApplication.run(YourApplication.class, args);
}
}
```
### 7.6 配置 FenixJPA 模块)
在您的 application.yml 或 application.properties 文件中添加 Fenix 配置:
```yaml
fenix:
# 是否开启 Fenix
enabled: true
# SQL 执行后的输出格式console: 控制台彩色输出; html: 彩色 HTML 输出; text: 纯文本输出
output-format: console
```
### 7.7 配置数据源
在您的 application.yml 或 application.properties 文件中配置数据源:
```yaml
spring:
datasource:
url: jdbc:mysql://localhost:3306/your_database
username: your_username
password: your_password
driver-class-name: com.mysql.cj.jdbc.Driver
```
### 7.8 测试集成效果
完成以上步骤后,您可以运行您的应用程序并测试以下功能:
1. 创建实体POST /employee/save
2. 查询列表GET /employee/list 或 POST /employee/list带条件
3. 查询详情GET /employee/detail/{id}
4. 删除实体GET /employee/remove/{id}
通过以上步骤,您就可以成功在现有项目中集成 Spring Boot Service Template 的能力,快速实现 CRUD 功能。
### 7.9 不同数据库实现方式的差异
#### 7.9.1 JPA 模块特点
- 基于 Spring Data JPA提供完整的 JPA 功能
- 支持 QueryDSL 类型安全查询
- 支持 Fenix 动态查询
- 自动审计功能(创建时间、修改时间)
- 需要配置 @EnableJpaAuditing
#### 7.9.2 Easy Query 模块特点
- 基于 Easy Query提供类型安全的查询构建
- 支持逻辑删除(@LogicDelete 注解)
- 实体类需要实现 ProxyEntityAvailable 接口以支持代理查询
- 支持雪花 ID 生成
- 查询性能优异
- 提供丰富的查询 APIeq、ne、like、gt、lt、in、between 等)
#### 7.9.3 Xbatis 模块特点
- 基于 Xbatis增强的 MyBatis提供灵活的 SQL 控制
- 支持逻辑删除(@LogicDelete@LogicDeleteTime 注解)
- 支持雪花 ID 生成
- 适合复杂查询场景
- MybatisBasicMapper 继承 BasicMapper提供基本 CRUD 操作,通常不需要编写 Mapper XML
- 提供链式查询 APIQueryChain构建复杂查询条件
根据您的项目需求和技术栈,选择最适合的数据库实现方式。
### 7.10 Easy Query 模块集成示例
#### 7.10.1 创建实体类EQ 模块)
创建实体类并继承 SimpleEntity实现 ProxyEntityAvailable 接口:
```java
import com.easy.query.core.proxy.AbstractProxyEntity;
import com.easy.query.core.proxy.ProxyEntityAvailable;
import com.lanyuanxiaoyao.service.template.database.eq.entity.SimpleEntity;
import com.lanyuanxiaoyao.service.template.database.eq.entity.TableIndex;
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.FieldNameConstants;
@Getter
@Setter
@FieldNameConstants
@TableIndex // EQ 注解,定义表名
public class Employee extends SimpleEntity implements ProxyEntityAvailable<Employee, EmployeeProxy> {
private String name;
private Integer age;
// 需要生成的代理类
}
```
#### 7.10.2 创建控制器类EQ 模块)
创建控制器类并继承 SimpleControllerSupport注意额外的泛型参数 PROXY
```java
import com.easy.query.core.proxy.AbstractProxyEntity;
import com.easy.query.core.proxy.ProxyEntityAvailable;
import com.lanyuanxiaoyao.service.template.database.eq.controller.SimpleControllerSupport;
import com.lanyuanxiaoyao.service.template.database.eq.service.SimpleServiceSupport;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("employee")
public class EmployeeController extends SimpleControllerSupport<
Employee, // ENTITY
EmployeeProxy, // PROXY需要生成
EmployeeSaveItem, // SAVE_ITEM
EmployeeListItem, // LIST_ITEM
EmployeeDetailItem> { // DETAIL_ITEM
public EmployeeController(SimpleServiceSupport<Employee, EmployeeProxy> service) {
super(service);
}
// 实现三个 Mapper 方法,与 JPA 模块相同
@Override
protected Function<EmployeeSaveItem, Employee> saveItemMapper() {
return item -> {
Employee employee = new Employee();
employee.setId(item.getId());
employee.setName(item.getName());
employee.setAge(item.getAge());
return employee;
};
}
@Override
protected Function<Employee, EmployeeListItem> listItemMapper() {
return employee -> {
EmployeeListItem item = new EmployeeListItem();
item.setId(employee.getId());
item.setName(employee.getName());
item.setAge(employee.getAge());
return item;
};
}
@Override
protected Function<Employee, EmployeeDetailItem> detailItemMapper() {
return employee -> {
EmployeeDetailItem item = new EmployeeDetailItem();
item.setId(employee.getId());
item.setName(employee.getName());
item.setAge(employee.getAge());
return item;
};
}
}
```
### 7.11 Xbatis 模块集成示例
#### 7.11.1 创建实体类Xbatis 模块)
创建实体类并继承 SimpleEntity
```java
import com.lanyuanxiaoyao.service.template.database.xbatis.entity.SimpleEntity;
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.FieldNameConstants;
@Getter
@Setter
@FieldNameConstants
public class Employee extends SimpleEntity {
private String name;
private Integer age;
}
```
#### 7.11.2 创建 Mapper 接口Xbatis 模块)
创建 Mapper 接口并继承 MybatisBasicMapper
```java
import com.lanyuanxiaoyao.service.template.database.xbatis.mapper.MybatisBasicMapper;
import org.springframework.stereotype.Repository;
@Repository
public interface EmployeeMapper extends MybatisBasicMapper {
// MybatisBasicMapper 已经提供了基本 CRUD 操作
// 可以添加自定义查询方法
}
```
#### 7.11.3 创建服务类Xbatis 模块)
创建服务类并继承 SimpleServiceSupport传入实体类和 Mapper
```java
import com.lanyuanxiaoyao.service.template.database.xbatis.mapper.MybatisBasicMapper;
import com.lanyuanxiaoyao.service.template.database.xbatis.service.SimpleServiceSupport;
import org.springframework.stereotype.Service;
@Service
public class EmployeeService extends SimpleServiceSupport<Employee> {
public EmployeeService(MybatisBasicMapper mapper) {
super(Employee.class, mapper);
}
// 自定义业务方法
}
```
### 7.12 模块对比总结
| 特性 | JPA 模块 | EQ 模块 | Xbatis 模块 |
|------|----------|---------|------------|
| 类型安全查询 | ✅ QueryDSL + Criteria API | ✅ 代理 API | ❌ 链式 API |
| 审计功能 | ✅ 自动审计 | ❌ 需手动实现 | ❌ 需手动实现 |
| 逻辑删除 | ❌ 仅物理删除 | ✅ @LogicDelete | ✅ @LogicDelete + @LogicDeleteTime |
| 实体复杂度 | 低(仅需继承) | 中(需实现 ProxyEntityAvailable | 低(仅需继承) |
| SQL 控制 | 中JPQL + Criteria | 低(构建器 API | 高(支持自定义 SQL |
| 查询灵活性 | 高 | 中 | 高 |
| 配置复杂度 | 中(需要编译插件配置) | 中(需要编译插件配置) | 低 |
| 适用场景 | 标准 JPA 项目,需要审计 | 需要类型安全查询和逻辑删除 | 复杂查询场景,需要 SQL 控制 |
根据您的项目需求和技术栈,选择最适合的数据库实现方式。
### 7.13 完整项目集成示例
本章节通过一个完整的"用户管理系统"示例,演示如何在独立项目中集成和使用 Spring Boot Service Template。以 JPA 模块为例,展示从依赖引入到运行测试的完整流程。
#### 7.13.1 项目初始化
创建一个新的 Spring Boot 项目,项目结构如下:
```
user-management/
├── src/main/java/com/example/usermanagement/
│ ├── UserManagementApplication.java # 主应用类
│ ├── controller/
│ │ └── UserController.java # 用户控制器
│ ├── service/
│ │ └── UserService.java # 用户服务
│ ├── repository/
│ │ └── UserRepository.java # 用户仓储
│ ├── entity/
│ │ └── User.java # 用户实体
│ └── dto/
│ ├── UserSaveItem.java # 保存 DTO
│ ├── UserListItem.java # 列表 DTO
│ └── UserDetailItem.java # 详情 DTO
├── src/main/resources/
│ └── application.yml # 应用配置
└── pom.xml # Maven 配置
```
#### 7.13.2 配置 pom.xml
在 pom.xml 中添加依赖和插件配置:
```xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>4.0.0</version>
<relativePath/>
</parent>
<groupId>com.example</groupId>
<artifactId>user-management</artifactId>
<version>1.0.0-SNAPSHOT</version>
<name>User Management</name>
<properties>
<java.version>17</java.version>
<spring-boot-service-template.version>1.1.0-SNAPSHOT</spring-boot-service-template.version>
<hibernate.version>7.1.8.Final</hibernate.version>
<querydsl.version>7.1</querydsl.version>
</properties>
<dependencies>
<!-- Spring Boot 基础依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 数据库相关依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<!-- Spring Boot Service Template 依赖 -->
<dependency>
<groupId>com.lanyuanxiaoyao</groupId>
<artifactId>spring-boot-service-template-database-jpa</artifactId>
<version>${spring-boot-service-template.version}</version>
</dependency>
<!-- 其他依赖 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.14.1</version>
<configuration>
<annotationProcessorPaths>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</path>
<path>
<groupId>org.hibernate.orm</groupId>
<artifactId>hibernate-jpamodelgen</artifactId>
<version>${hibernate.version}</version>
</path>
<path>
<groupId>io.github.openfeign.querydsl</groupId>
<artifactId>querydsl-apt</artifactId>
<version>${querydsl.version}</version>
<classifier>jpa</classifier>
</path>
<path>
<groupId>jakarta.persistence</groupId>
<artifactId>jakarta.persistence-api</artifactId>
<version>3.2.0</version>
</path>
</annotationProcessorPaths>
<compilerArgs>
<arg>-Aquerydsl.entityAccessors=true</arg>
<arg>-Aquerydsl.createDefaultVariable=true</arg>
</compilerArgs>
</configuration>
</plugin>
</plugins>
</build>
</project>
```
#### 7.13.3 配置 application.yml
在 application.yml 中配置数据源和 Fenix
```yaml
server:
port: 8080
spring:
application:
name: user-management
datasource:
url: jdbc:h2:mem:userdb
driver-class-name: org.h2.Driver
username: sa
password:
h2:
console:
enabled: true
jpa:
hibernate:
ddl-auto: update
show-sql: true
fenix:
enabled: true
output-format: console
logging:
level:
com.example.usermanagement: DEBUG
com.lanyuanxiaoyao.service.template: DEBUG
```
#### 7.13.4 创建主应用类
创建 UserManagementApplication.java启用 JPA 审计:
```java
package com.example.usermanagement;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
@SpringBootApplication
@EnableJpaAuditing
public class UserManagementApplication {
public static void main(String[] args) {
SpringApplication.run(UserManagementApplication.class, args);
}
}
```
#### 7.13.5 创建实体类
创建 User.java继承 SimpleEntity
```java
package com.example.usermanagement.entity;
import com.lanyuanxiaoyao.service.template.database.jpa.entity.SimpleEntity;
import jakarta.persistence.Entity;
import jakarta.persistence.Table;
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.FieldNameConstants;
@Getter
@Setter
@FieldNameConstants
@Entity
@Table(name = "users")
public class User extends SimpleEntity {
/**
* 用户名
*/
private String username;
/**
* 邮箱
*/
private String email;
/**
* 年龄
*/
private Integer age;
/**
* 状态ACTIVE, INACTIVE
*/
private String status;
}
```
#### 7.13.6 创建仓储接口
创建 UserRepository.java继承 SimpleRepository
```java
package com.example.usermanagement.repository;
import com.example.usermanagement.entity.User;
import com.lanyuanxiaoyao.service.template.database.jpa.repository.SimpleRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface UserRepository extends SimpleRepository<User> {
// 可以添加自定义查询方法
// 例如User findByEmail(String email);
}
```
#### 7.13.7 创建 DTO 类
创建三个 DTO 类:
**UserSaveItem.java**
```java
package com.example.usermanagement.dto;
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.FieldNameConstants;
@Getter
@Setter
@FieldNameConstants
public class UserSaveItem {
private Long id;
private String username;
private String email;
private Integer age;
private String status;
}
```
**UserListItem.java**
```java
package com.example.usermanagement.dto;
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.FieldNameConstants;
@Getter
@Setter
@FieldNameConstants
public class UserListItem {
private Long id;
private String username;
private String email;
private Integer age;
private String status;
}
```
**UserDetailItem.java**
```java
package com.example.usermanagement.dto;
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.FieldNameConstants;
import java.time.LocalDateTime;
@Getter
@Setter
@FieldNameConstants
public class UserDetailItem {
private Long id;
private String username;
private String email;
private Integer age;
private String status;
private LocalDateTime createdTime;
private LocalDateTime modifiedTime;
}
```
#### 7.13.8 创建服务类
创建 UserService.java继承 SimpleServiceSupport
```java
package com.example.usermanagement.service;
import com.example.usermanagement.entity.User;
import com.example.usermanagement.repository.UserRepository;
import com.lanyuanxiaoyao.service.template.database.jpa.service.SimpleServiceSupport;
import org.springframework.stereotype.Service;
@Service
public class UserService extends SimpleServiceSupport<User> {
public UserService(UserRepository repository) {
super(repository);
}
// 可以添加自定义业务方法
// 例如public User findByEmail(String email) { ... }
}
```
#### 7.13.9 创建控制器类
创建 UserController.java继承 SimpleControllerSupport实现三个 Mapper 方法:
```java
package com.example.usermanagement.controller;
import com.example.usermanagement.dto.UserDetailItem;
import com.example.usermanagement.dto.UserListItem;
import com.example.usermanagement.dto.UserSaveItem;
import com.example.usermanagement.entity.User;
import com.example.usermanagement.service.UserService;
import com.lanyuanxiaoyao.service.template.database.jpa.controller.SimpleControllerSupport;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.function.Function;
@RestController
@RequestMapping("/users")
public class UserController extends SimpleControllerSupport<User, UserSaveItem, UserListItem, UserDetailItem> {
public UserController(UserService service) {
super(service);
}
@Override
protected Function<UserSaveItem, User> saveItemMapper() {
return item -> {
User user = new User();
user.setId(item.getId());
user.setUsername(item.getUsername());
user.setEmail(item.getEmail());
user.setAge(item.getAge());
user.setStatus(item.getStatus());
return user;
};
}
@Override
protected Function<User, UserListItem> listItemMapper() {
return user -> {
UserListItem item = new UserListItem();
item.setId(user.getId());
item.setUsername(user.getUsername());
item.setEmail(user.getEmail());
item.setAge(user.getAge());
item.setStatus(user.getStatus());
return item;
};
}
@Override
protected Function<User, UserDetailItem> detailItemMapper() {
return user -> {
UserDetailItem item = new UserDetailItem();
item.setId(user.getId());
item.setUsername(user.getUsername());
item.setEmail(user.getEmail());
item.setAge(user.getAge());
item.setStatus(user.getStatus());
item.setCreatedTime(user.getCreatedTime());
item.setModifiedTime(user.getModifiedTime());
return item;
};
}
}
```
#### 7.13.10 运行和测试
1. **启动应用**
```bash
mvn spring-boot:run
```
2. **访问 H2 控制台**
```
http://localhost:8080/h2-console
```
3. **测试 API**
**创建用户**
```bash
curl -X POST http://localhost:8080/users/save \
-H "Content-Type: application/json" \
-d '{
"username": "zhangsan",
"email": "zhangsan@example.com",
"age": 25,
"status": "ACTIVE"
}'
```
**查询所有用户**
```bash
curl http://localhost:8080/users/list
```
**条件查询用户**
```bash
curl -X POST http://localhost:8080/users/list \
-H "Content-Type: application/json" \
-d '{
"query": {
"equal": {
"status": "ACTIVE"
},
"greatEqual": {
"age": 20
}
},
"sort": [
{
"column": "age",
"direction": "DESC"
}
],
"page": {
"index": 1,
"size": 10
}
}'
```
**查询用户详情**
```bash
curl http://localhost:8080/users/detail/{userId}
```
**删除用户**
```bash
curl http://localhost:8080/users/remove/{userId}
```
#### 7.13.11 项目结构总结
通过以上步骤,您已经成功集成了 Spring Boot Service Template获得了以下功能
1. **自动 CRUD 接口**:无需手动编写增删改查的 Controller 方法
2. **统一响应格式**:所有 API 返回标准的 GlobalResponse 格式
3. **自动审计**createdTime 和 modifiedTime 自动维护
4. **雪花 ID**:自动生成分布式唯一 ID
5. **复杂查询**:支持 21 种查询条件类型
6. **分页排序**:内置分页和排序功能
#### 7.13.12 常见问题
**Q: 如何添加自定义业务逻辑?**
A: 在 Service 类中添加自定义方法,然后在 Controller 中注入并使用。
**Q: 如何修改默认的 URL 路径?**
A: 在 Controller 的 @RequestMapping 注解中修改路径。
**Q: 如何禁用某个接口?**
A: 可以不实现对应的 Mapper 方法,或者在 Controller 中使用 @GetMapping/@PostMapping 注解时指定不同的路径。
**Q: 如何集成其他数据库MySQL、PostgreSQL**
A: 在 application.yml 中修改 datasource 配置,并添加对应的数据库驱动依赖。
**Q: 如何使用 Easy Query 或 Xbatis 替代 JPA**
A: 参考 7.10 和 7.11 节的集成示例,替换对应的依赖和实现类即可。
## 8. 更新日志
### 1.1.0-SNAPSHOT (当前版本)
#### 文档更新
- 更新技术栈版本信息,补充 MapStruct Plus 1.5.0、JSpecify 1.0.0 等依赖
- 补充通用组件说明P6spy、Datasource Proxy
- 更新 database-common 模块说明,详细描述各个接口和类的功能
- 更新 JPA 模块说明,添加 SnowflakeId 注解和生成器的详细说明
- 更新 EQ 模块说明,说明需要实现 ProxyEntityAvailable 接口
- 更新 Xbatis 模块说明,说明 MybatisBasicMapper 继承 BasicMapper
- 添加测试模块说明,描述 AbstractTestApplication 的测试流程
- 更新设计模式部分,补充 QueryParser 的模板方法模式说明
- 更新核心特性,补充查询解析器模板、异常处理等特性
- 更新数据实体设计,详细说明各种实体类的用途和注解
- 添加查询解析器详细说明,描述 QueryParser 抽象类和 21 种查询条件
- 更新统一响应格式,补充 GlobalResponse 工厂方法列表
- 修正 Easy Query 模块特点,说明需要实现 ProxyEntityAvailable 接口
- 修正 Xbatis 模块特点,说明 MybatisBasicMapper 的功能
- 添加 EQ 模块集成示例,包含实体类和控制器示例
- 添加 Xbatis 模块集成示例包含实体类、Mapper 和服务示例
- 添加模块对比总结,从多个维度对比三种数据库实现方式
- 添加当前版本信息到项目概述