一个用于快速学习 Spring Boot 生产开发的脚手架项目,包含完整的 CRUD 示例、分页查询、全局异常处理、API 文档等生产级功能。
| 技术 | 版本 | 说明 |
|---|---|---|
| Spring Boot | 3.2.0 | 核心框架 |
| MyBatis | 3.0.3 | ORM 框架 |
| MySQL | 8.0+ | 数据库 |
| Druid | 1.2.20 | 数据库连接池 |
| PageHelper | 6.0.0 | 分页插件 |
| Lombok | 1.18.30 | 代码简化工具 |
| Knife4j | 4.3.0 | API 文档 |
| JDK | 17 | Java 版本 |
springboot-learning-scaffold/
├── src/main/java/com/example/demo/
│ ├── DemoApplication.java # 启动类
│ ├── common/ # 通用类
│ │ ├── Result.java # 统一响应结果
│ │ └── PageResult.java # 分页结果封装
│ ├── config/ # 配置类
│ │ └── MyBatisConfig.java # MyBatis 配置
│ ├── controller/ # 控制器层
│ │ ├── HelloController.java # 测试接口
│ │ └── UserController.java # 用户管理接口
│ ├── entity/ # 实体类
│ │ ├── User.java # 用户实体
│ │ ├── dto/ # 数据传输对象
│ │ │ └── UserQueryDTO.java # 用户查询条件
│ │ └── vo/ # 视图对象
│ ├── exception/ # 异常处理
│ │ ├── BusinessException.java # 业务异常
│ │ └── GlobalExceptionHandler.java # 全局异常处理器
│ ├── mapper/ # 数据访问层
│ │ └── UserMapper.java # 用户 Mapper 接口
│ └── service/ # 业务逻辑层
│ ├── UserService.java # 用户服务接口
│ └── impl/
│ └── UserServiceImpl.java # 用户服务实现
├── src/main/resources/
│ ├── application.yml # 主配置文件
│ ├── application-dev.yml # 开发环境配置
│ └── mapper/
│ └── UserMapper.xml # 用户 SQL 映射文件
├── src/test/java/ # 测试代码
├── sql/
│ └── init.sql # 数据库初始化脚本
├── pom.xml # Maven 配置文件
├── settings.xml # Maven settings(指定本地仓库)
└── README.md # 项目说明文档
- JDK 17+
- Maven 3.8+
- MySQL 8.0+
执行 sql/init.sql 脚本创建数据库和测试数据:
# 登录 MySQL
mysql -u root -p
# 执行初始化脚本
source sql/init.sql或手动执行:
CREATE DATABASE demo_db CHARACTER SET utf8mb4;
USE demo_db;
-- 执行 init.sql 中的建表和插入语句编辑 src/main/resources/application-dev.yml,修改数据库连接信息:
spring:
datasource:
url: jdbc:mysql://localhost:3306/demo_db?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
username: root
password: your_password使用指定 Maven 路径和仓库:
# 进入项目目录
cd springboot-learning-scaffold
# 方式一:使用项目自带的 settings.xml(已配置阿里云镜像和本地仓库)
mvn -s settings.xml clean install
# 方式二:直接运行(确保 Maven 环境变量已配置)
mvn spring-boot:run或者在 IDE 中直接运行 DemoApplication 类的 main 方法。
访问以下地址验证服务:
- 首页:
http://localhost:8080/ - API 文档:
http://localhost:8080/doc.html - Swagger UI:
http://localhost:8080/swagger-ui.html
// 成功响应
Result.success(data);
Result.success("操作成功", data);
// 失败响应
Result.error("错误信息");
Result.error(500, "错误信息");
// 其他状态
Result.badRequest("参数错误");
Result.notFound("资源不存在");// Controller 层
@PostMapping("/page")
public Result<PageResult<User>> pageList(@RequestBody UserQueryDTO queryDTO) {
return Result.success(userService.pageList(queryDTO));
}
// Service 层
@Override
public PageResult<User> pageList(UserQueryDTO queryDTO) {
PageHelper.startPage(queryDTO.getPageNum(), queryDTO.getPageSize());
List<User> list = userMapper.selectByCondition(queryDTO);
PageInfo<User> pageInfo = new PageInfo<>(list);
return PageResult.of(pageInfo);
}@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(BusinessException.class)
public Result<Void> handleBusinessException(BusinessException e) {
return Result.error(e.getCode(), e.getMessage());
}
@ExceptionHandler(MethodArgumentNotValidException.class)
public Result<Void> handleValidException(MethodArgumentNotValidException e) {
// 处理参数校验失败
}
}<!-- 条件查询 -->
<select id="selectByCondition" resultMap="BaseResultMap">
SELECT * FROM sys_user
<where>
<if test="username != null and username != ''">
AND username LIKE CONCAT('%', #{username}, '%')
</if>
<if test="status != null">
AND status = #{status}
</if>
</where>
</select>
<!-- 动态更新 -->
<update id="update">
UPDATE sys_user
<set>
<if test="username != null">username = #{username},</if>
<if test="nickname != null">nickname = #{nickname},</if>
update_time = NOW()
</set>
WHERE id = #{id}
</update>@Data
public class User {
@NotBlank(message = "用户名不能为空")
private String username;
@Email(message = "邮箱格式不正确")
private String email;
@Pattern(regexp = "^1[3-9]\\d{9}$", message = "手机号格式不正确")
private String phone;
}| 方法 | 接口 | 说明 |
|---|---|---|
| GET | /api/user/{id} |
根据ID查询用户 |
| GET | /api/user/list |
查询所有用户 |
| POST | /api/user/page |
分页查询用户 |
| POST | /api/user |
新增用户 |
| PUT | /api/user/{id} |
更新用户 |
| DELETE | /api/user/{id} |
删除用户 |
| DELETE | /api/user/batch?ids=1,2,3 |
批量删除 |
| PUT | /api/user/{id}/status/{status} |
更新状态 |
| 方法 | 接口 | 说明 |
|---|---|---|
| GET | / |
服务信息 |
| GET | /hello |
Hello World |
spring:
profiles:
active: dev # 激活开发环境配置
datasource:
# 数据源配置
mybatis:
# MyBatis 配置
pagehelper:
# 分页插件配置
logging:
# 日志配置application-dev.yml:开发环境application-test.yml:测试环境(可自建)application-prod.yml:生产环境(可自建)
切换环境:
spring:
profiles:
active: prod # 切换到生产环境Controller -> Service -> Mapper -> XML
↓ ↓ ↓
接收请求 业务逻辑 数据访问
参数校验 事务控制 SQL编写
- 类名:大驼峰(
UserService) - 方法名:小驼峰(
getById) - 数据库表:
sys_user(小写下划线) - 数据库字段:
user_name(小写下划线) - Mapper XML:与接口同名(
UserMapper.xml)
在 Service 层的方法上添加 @Transactional:
@Transactional(rollbackFor = Exception.class)
public void save(User user) {
// 涉及多个数据库操作时使用
}@Slf4j
@Service
public class UserServiceImpl implements UserService {
public void save(User user) {
log.debug("调试信息");
log.info("普通信息");
log.warn("警告信息");
log.error("错误信息", exception);
}
}- 数据库密码:生产环境务必使用加密存储
- SQL 注入:使用
#{}占位符,不要拼接 SQL - 敏感信息:接口返回时清除密码等敏感字段
- 事务边界:Service 层方法控制事务,避免跨服务事务
- 异常处理:统一使用 BusinessException 抛出业务异常
- 基础入门:理解 Spring Boot 自动配置、Starter 机制
- 数据访问:掌握 MyBatis 基本 CRUD、动态 SQL
- 分页插件:PageHelper 的使用和原理
- API 文档:Knife4j/Swagger 注解的使用
- 异常处理:全局异常处理机制
- 参数校验:JSR-303 校验注解
- 日志配置:SLF4J + Logback 日志管理
- 性能优化:连接池配置、SQL 优化、缓存使用
本项目仅供学习使用。