1. 项目概述:现代Java后端开发的标准配置
这套技术组合堪称当前Java企业级开发的黄金搭档,我在最近三个生产项目中都采用了完全相同的技术栈。SpringBoot3作为基础框架提供了现代化的开发体验,MyBatis-Plus在持久层大幅减少了样板代码,MySQL作为经典关系型数据库稳定可靠,而Swagger则让API文档维护变得轻松愉快。
这个配置最精妙之处在于它的平衡性——既有SpringBoot3带来的新特性支持(比如JDK17基线、GraalVM原生镜像准备),又通过MyBatis-Plus保留了SQL层面的灵活控制权。我曾对比过JPA方案,在需要复杂查询和批量操作的场景下,MyBatis-Plus的性能优势能达到20-30%。
提示:SpringBoot3要求JDK17+环境,这是与2.x系列最大的区别点。如果还在用JDK8,需要先升级开发环境。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 环境准备与项目初始化
2.1 开发环境清单
这是我验证过的环境组合,建议新手直接采用相同版本避免兼容性问题:
| 组件 | 版本要求 | 备注 |
|---|---|---|
| JDK | 17+ | 推荐Amazon Corretto-17 |
| IDE | IntelliJ 2023.2+ | 社区版即可 |
| MySQL | 8.0.28+ | 必须开启INNODB引擎 |
| Maven | 3.8.6+ | 需要配置阿里云镜像 |
2.2 项目骨架搭建
使用Spring Initializr生成项目时,这几个依赖项必须勾选:
- Spring Web (构建RESTful API)
- MyBatis Framework (基础ORM支持)
- MySQL Driver (数据库连接)
我习惯用命令行初始化项目:
bash复制curl https://start.spring.io/starter.zip \
-d dependencies=web,mybatis,mysql \
-d javaVersion=17 \
-d type=maven-project \
-d bootVersion=3.1.0 \
-d groupId=com.example \
-d artifactId=demo \
-o demo.zip
解压后需要手动添加这些关键依赖到pom.xml:
xml复制<!-- MyBatis-Plus -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.3.1</version>
</dependency>
<!-- Swagger -->
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
<version>2.1.0</version>
</dependency>
<!-- 生产环境建议添加的监控组件 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
3. 核心配置文件详解
3.1 application.yml 基础配置
这是经过生产验证的配置模板,已经包含了性能优化参数:
yaml复制server:
port: 8080
servlet:
context-path: /api
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/demo?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai
username: root
password: 123456
hikari:
maximum-pool-size: 20
minimum-idle: 5
connection-timeout: 30000
idle-timeout: 600000
max-lifetime: 1800000
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
global-config:
db-config:
id-type: auto
logic-delete-field: deleted
logic-not-delete-value: 0
logic-delete-value: 1
springdoc:
swagger-ui:
path: /swagger-ui.html
tags-sorter: alpha
operations-sorter: alpha
api-docs:
path: /v3/api-docs
default-produces-media-type: application/json
关键配置说明:
- MySQL连接串必须包含时区参数(serverTimezone),否则会遇到令人头疼的时区异常
- HikariCP连接池参数根据2C4G服务器优化过,线上环境需要根据实际负载调整
- MyBatis-Plus的逻辑删除配置让软删除实现零编码
3.2 必须的Java配置类
3.2.1 MyBatis-Plus分页插件
java复制@Configuration
public class MyBatisPlusConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
// 分页插件
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
// 乐观锁插件
interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
return interceptor;
}
}
3.2.2 Swagger3配置(SpringDoc版)
java复制@Configuration
public class SwaggerConfig {
@Bean
public OpenAPI springShopOpenAPI() {
return new OpenAPI()
.info(new Info().title("API文档")
.description("SpringBoot3项目接口文档")
.version("v1.0")
.license(new License().name("Apache 2.0").url("http://springdoc.org")))
.externalDocs(new ExternalDocumentation()
.description("项目Wiki")
.url("https://github.com/yourrepo/wiki"));
}
}
重要提示:SpringBoot3不再支持传统的SpringFox Swagger,必须使用SpringDoc OpenAPI。两者的注解语法略有不同,迁移时需要注意。
4. 数据库层最佳实践
4.1 实体类设计示例
java复制@Data
@TableName("sys_user")
@ApiModel("用户实体")
public class User {
@TableId(type = IdType.AUTO)
@ApiModelProperty("用户ID")
private Long id;
@TableField("username")
@ApiModelProperty("登录账号")
private String account;
@TableField(fill = FieldFill.INSERT)
@ApiModelProperty("创建时间")
private LocalDateTime createTime;
@TableField(fill = FieldFill.INSERT_UPDATE)
@ApiModelProperty("更新时间")
private LocalDateTime updateTime;
@TableLogic
@ApiModelProperty("删除标记")
private Integer deleted;
}
4.2 Mapper接口与Service实现
4.2.1 基础Mapper
java复制public interface UserMapper extends BaseMapper<User> {
// 自定义复杂查询
@Select("SELECT * FROM sys_user WHERE username LIKE CONCAT('%',#{keyword},'%')")
List<User> searchByKeyword(@Param("keyword") String keyword);
}
4.2.2 Service层模板
java复制public interface UserService extends IService<User> {
// 自定义业务方法
Page<User> queryPage(Map<String, Object> params);
}
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
@Override
public Page<User> queryPage(Map<String, Object> params) {
QueryWrapper<User> wrapper = new QueryWrapper<>();
// 构建查询条件
String keyword = (String) params.get("keyword");
if (StringUtils.isNotBlank(keyword)) {
wrapper.like("username", keyword);
}
// 分页查询
return this.page(
new Page<>(Integer.parseInt(params.get("page").toString()),
Integer.parseInt(params.get("limit").toString())),
wrapper
);
}
}
5. 接口层与Swagger集成
5.1 RESTful控制器示例
java复制@RestController
@RequestMapping("/user")
@Tag(name = "用户管理", description = "用户相关操作接口")
public class UserController {
@Autowired
private UserService userService;
@GetMapping("/page")
@Operation(summary = "分页查询用户")
public R<Page<User>> queryPage(
@Parameter(description = "当前页码") @RequestParam Integer page,
@Parameter(description = "每页条数") @RequestParam Integer limit,
@Parameter(description = "搜索关键词") @RequestParam(required = false) String keyword) {
Map<String, Object> params = new HashMap<>();
params.put("page", page);
params.put("limit", limit);
params.put("keyword", keyword);
return R.ok(userService.queryPage(params));
}
@PostMapping("/save")
@Operation(summary = "保存用户")
public R<String> save(@RequestBody @Valid User user) {
userService.saveOrUpdate(user);
return R.ok("操作成功");
}
}
5.2 统一响应封装
java复制@Data
@ApiModel("统一响应结果")
public class R<T> implements Serializable {
@ApiModelProperty("响应码")
private Integer code;
@ApiModelProperty("响应消息")
private String msg;
@ApiModelProperty("响应数据")
private T data;
public static <T> R<T> ok(T data) {
R<T> r = new R<>();
r.setCode(200);
r.setMsg("success");
r.setData(data);
return r;
}
// 其他静态工厂方法...
}
6. 常见问题排查指南
6.1 启动时报错排查
问题1:java.lang.IllegalArgumentException: jdbcUrl is required...
- 检查项:
- application.yml中数据库连接配置缩进是否正确(必须2空格缩进)
- url中的参数是否包含特殊字符(建议URLEncode)
- 驱动类名是否写错(MySQL8+必须用com.mysql.cj.jdbc.Driver)
问题2:Failed to configure a DataSource...
- 解决方案:
java复制// 在启动类添加排除数据源自动配置
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
6.2 Swagger无法访问
现象:访问/swagger-ui.html返回404
- 排查步骤:
- 确认依赖是springdoc-openapi-starter-webmvc-ui
- 检查是否有安全拦截器拦截了/swagger-ui.html路径
- 查看启动日志是否有springdoc相关的初始化日志
6.3 MyBatis-Plus插件失效
典型场景:分页查询返回全部记录
- 解决方案:
- 确认配置类被Spring扫描到(添加@Configuration)
- 检查拦截器添加顺序(分页插件应该最先添加)
- 确保Page对象作为第一个参数(MP的硬性要求)
7. 生产环境优化建议
7.1 性能调优参数
在application-prod.yml中建议添加:
yaml复制spring:
datasource:
hikari:
pool-name: SpringBootHikariCP
maximum-pool-size: ${DB_MAX_CONN:20}
connection-timeout: 5000
validation-timeout: 1000
leak-detection-threshold: 30000
mybatis-plus:
mapper-locations: classpath*:/mapper/**/*.xml
configuration:
cache-enabled: true
lazy-loading-enabled: true
aggressive-lazy-loading: false
7.2 安全防护措施
- Swagger访问控制(添加Spring Security配置):
java复制@Bean
SecurityFilterChain swaggerSecurity(HttpSecurity http) throws Exception {
http.authorizeHttpRequests(auth -> auth
.requestMatchers("/swagger-ui/**").hasRole("ADMIN")
.requestMatchers("/v3/api-docs/**").authenticated()
);
return http.build();
}
- MySQL连接安全:
- 使用SSL连接(jdbcUrl添加useSSL=true)
- 配置白名单IP访问
- 定期更换高强度密码
8. 扩展功能集成
8.1 多数据源配置
java复制@Configuration
@MapperScan(basePackages = "com.example.mapper.db1", sqlSessionTemplateRef = "db1SqlSessionTemplate")
public class Db1Config {
@Bean
@ConfigurationProperties("spring.datasource.db1")
public DataSource db1DataSource() {
return DataSourceBuilder.create().build();
}
@Bean
public SqlSessionFactory db1SqlSessionFactory(@Qualifier("db1DataSource") DataSource dataSource) throws Exception {
MybatisSqlSessionFactoryBean factory = new MybatisSqlSessionFactoryBean();
factory.setDataSource(dataSource);
factory.setMapperLocations(new PathMatchingResourcePatternResolver()
.getResources("classpath:mapper/db1/*.xml"));
return factory.getObject();
}
@Bean
public SqlSessionTemplate db1SqlSessionTemplate(
@Qualifier("db1SqlSessionFactory") SqlSessionFactory sqlSessionFactory) {
return new SqlSessionTemplate(sqlSessionFactory);
}
}
8.2 动态数据源切换
- 添加依赖:
xml复制<dependency>
<groupId>com.baomidou</groupId>
<artifactId>dynamic-datasource-spring-boot-starter</artifactId>
<version>3.6.1</version>
</dependency>
- 配置多数据源:
yaml复制spring:
datasource:
dynamic:
primary: master
strict: false
datasource:
master:
url: jdbc:mysql://localhost:3306/master
username: root
password: 123456
slave1:
url: jdbc:mysql://localhost:3306/slave1
username: root
password: 123456
- 使用注解切换:
java复制@DS("slave1") // 指定数据源
public List<User> getSlaveUsers() {
return userMapper.selectList(null);
}
这套基础配置已经在我参与的多个电商和OA系统中验证过稳定性,特别适合快速启动中小型项目。根据我的经验,在开发前期就建立好规范的配置模板,能为后期维护节省至少30%的工作量。
