1. 项目概述
作为一名常年混迹在Java后端开发领域的老兵,我深知快速搭建一个基础工程框架对开发效率的重要性。今天要分享的这个SpringBoot3 + MyBatis-Plus组合,可以说是当前Java企业级开发中最受欢迎的"黄金搭档"。
这个组合到底有多香?SpringBoot3作为Spring家族的最新成员,带来了GraalVM原生镜像支持、JDK17基线等新特性;而MyBatis-Plus则在MyBatis基础上提供了强大的CRUD增强,让数据库操作变得异常简单。两者结合,既能享受Spring生态的丰富功能,又能避免传统MyBatis的样板代码问题。
提示:虽然标题说是5分钟,但实际根据网络环境和开发工具的不同,可能需要7-10分钟。不过相比传统方式动辄半小时的配置,这已经算是"光速"了。
2. 环境准备
2.1 基础环境要求
在开始之前,我们需要确保本地开发环境满足以下要求:
- JDK 17或更高版本(SpringBoot3的最低要求)
- Maven 3.6.3+ 或 Gradle 7.x(本文以Maven为例)
- IDE(IntelliJ IDEA推荐使用2021.3+版本)
- MySQL 5.7+/PostgreSQL(或其他MyBatis-Plus支持的数据库)
2.2 开发工具配置建议
这里分享几个我个人的工具配置技巧:
IDEA插件:务必安装Lombok插件,否则编译会报错。同时推荐安装MyBatisX插件,可以获得更好的Mapper XML导航体验。
Maven镜像:建议在settings.xml中配置阿里云镜像,可以大幅提升依赖下载速度:
<mirror> <id>aliyunmaven</id> <mirrorOf>*</mirrorOf> <name>阿里云公共仓库</name> <url>https://maven.aliyun.com/repository/public</url> </mirror>- 数据库工具:推荐使用DBeaver或Navicat作为数据库客户端,方便后续的表结构查看和数据验证。
3. 项目创建与基础配置
3.1 使用Spring Initializr创建项目
最快的方式是通过Spring官方提供的初始化工具:
访问 start.spring.io
选择以下配置:
- Project: Maven Project
- Language: Java
- Spring Boot: 3.0.x(最新稳定版)
- 项目元信息(按需填写)
- Packaging: Jar
- Java: 17
添加依赖:
- Spring Web
- Lombok
- MyBatis Framework
- MySQL Driver
点击"Generate"下载项目压缩包,解压后用IDE打开。
注意:如果你使用的是IntelliJ IDEA Ultimate版,可以直接在IDE中使用Spring Initializr向导,更加方便。
3.2 添加MyBatis-Plus依赖
Spring Initializr只提供了基础的MyBatis依赖,我们需要手动添加MyBatis-Plus。打开pom.xml,在dependencies部分添加:
<dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.5.3.1</version> </dependency>同时,建议添加MyBatis-Plus的代码生成器依赖(后续会用到):
<dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-generator</artifactId> <version>3.5.3.1</version> <scope>provided</scope> </dependency>3.3 基础配置
在application.properties或application.yml中添加数据库配置。以yml格式为例:
spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/your_database?useSSL=false&serverTimezone=UTC username: root password: your_password mybatis-plus: configuration: log-impl: org.apache.ibatis.logging.stdout.StdOutImpl # 开启SQL日志 global-config: db-config: id-type: auto # 主键自增策略4. 快速开发CRUD接口
4.1 创建实体类
假设我们要开发一个用户管理系统,首先创建User实体类:
@Data @TableName("sys_user") // 指定表名 public class User { @TableId(type = IdType.AUTO) // 主键自增 private Long id; private String username; private String password; private String email; private Integer status; @TableField(fill = FieldFill.INSERT) // 自动填充 private LocalDateTime createTime; @TableField(fill = FieldFill.INSERT_UPDATE) private LocalDateTime updateTime; }4.2 创建Mapper接口
MyBatis-Plus的强大之处在于,基础的CRUD操作几乎不需要写SQL:
@Mapper public interface UserMapper extends BaseMapper<User> { // 基础的CRUD方法已经由BaseMapper提供 }4.3 创建Service层
public interface UserService extends IService<User> { // 可以扩展自定义方法 } @Service public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService { // 实现类 }4.4 创建Controller
@RestController @RequestMapping("/user") public class UserController { @Autowired private UserService userService; @GetMapping("/{id}") public Result<User> getById(@PathVariable Long id) { return Result.success(userService.getById(id)); } @PostMapping public Result<Boolean> save(@RequestBody User user) { return Result.success(userService.save(user)); } // 其他CRUD方法... }5. 高级功能配置
5.1 自动填充配置
实现MetaObjectHandler接口来处理自动填充字段:
@Component public class MyMetaObjectHandler implements MetaObjectHandler { @Override public void insertFill(MetaObject metaObject) { this.strictInsertFill(metaObject, "createTime", LocalDateTime.class, LocalDateTime.now()); this.strictInsertFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now()); } @Override public void updateFill(MetaObject metaObject) { this.strictUpdateFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now()); } }5.2 分页插件配置
添加分页插件配置类:
@Configuration public class MyBatisPlusConfig { @Bean public MybatisPlusInterceptor mybatisPlusInterceptor() { MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL)); return interceptor; } }然后在Service中就可以使用分页查询了:
Page<User> page = new Page<>(1, 10); // 当前页,每页大小 Page<User> result = userService.page(page);5.3 代码生成器
MyBatis-Plus提供了一个强大的代码生成器,可以快速生成Entity、Mapper、Service、Controller等代码:
public class CodeGenerator { public static void main(String[] args) { FastAutoGenerator.create("jdbc:mysql://localhost:3306/your_database", "root", "your_password") .globalConfig(builder -> { builder.author("your_name") // 设置作者 .outputDir(System.getProperty("user.dir") + "/src/main/java"); // 输出目录 }) .packageConfig(builder -> { builder.parent("com.example") // 父包名 .moduleName("demo"); // 模块名 }) .strategyConfig(builder -> { builder.addInclude("sys_user") // 表名 .entityBuilder() .enableLombok() .controllerBuilder() .enableRestStyle(); // 开启@RestController }) .execute(); } }6. 常见问题与解决方案
6.1 数据库连接问题
问题现象:启动时报"Failed to configure a DataSource"错误。
解决方案:
- 检查数据库连接URL、用户名和密码是否正确
- 确保数据库服务已启动
- 如果是MySQL 8.0+,确认驱动类名是
com.mysql.cj.jdbc.Driver - 可以在启动类上添加
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})临时排除数据源自动配置
6.2 MyBatis-Plus与MyBatis冲突
问题现象:启动时报"BeanDefinitionOverrideException"。
解决方案:
- 确保只引入了mybatis-plus-boot-starter,不要同时引入mybatis-spring-boot-starter
- 如果必须同时使用,可以在application.yml中添加:
spring: main: allow-bean-definition-overriding: true6.3 Lombok不生效
问题现象:编译时报"找不到getter/setter方法"。
解决方案:
- 确保IDE安装了Lombok插件
- 在IDEA中开启注解处理:Settings → Build → Compiler → Annotation Processors → 勾选Enable annotation processing
- 如果是Eclipse,需要下载Lombok.jar并运行安装
7. 性能优化建议
7.1 SQL性能优化
- 启用二级缓存:在配置类中添加缓存配置
@Bean public MybatisPlusInterceptor mybatisPlusInterceptor() { MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL)); // 添加缓存拦截器 interceptor.addInnerInterceptor(new CachingInnerInterceptor()); return interceptor; }- 合理使用索引:在经常查询的字段上添加@TableField注解的condition属性
@TableField(condition = SqlCondition.LIKE) private String username;7.2 服务层优化
- 批量操作:使用MyBatis-Plus提供的批量操作方法
boolean success = userService.saveBatch(userList); // 批量插入- 逻辑删除:配置逻辑删除字段
mybatis-plus: global-config: db-config: logic-delete-field: deleted # 逻辑删除字段名 logic-not-delete-value: 0 # 未删除值 logic-delete-value: 1 # 删除值8. 项目结构最佳实践
经过多年实践,我总结了一个比较合理的项目结构:
src/main/java ├── com.example.demo │ ├── config # 配置类 │ ├── controller # 控制器 │ ├── entity # 实体类 │ ├── enums # 枚举类 │ ├── mapper # Mapper接口 │ ├── service # 服务接口 │ │ └── impl # 服务实现 │ ├── util # 工具类 │ └── vo # 视图对象 src/main/resources ├── application.yml # 主配置文件 └── mapper # XML映射文件(可选)对于更复杂的项目,可以考虑按功能模块划分:
src/main/java ├── com.example.demo │ ├── module │ │ ├── user │ │ │ ├── controller │ │ │ ├── entity │ │ │ ├── mapper │ │ │ └── service │ │ └── product │ │ ├── controller │ │ ├── entity │ │ ├── mapper │ │ └── service9. 扩展功能集成
9.1 集成Swagger文档
添加依赖:
<dependency> <groupId>org.springdoc</groupId> <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId> <version>2.0.2</version> </dependency>配置类:
@Configuration public class SwaggerConfig { @Bean public OpenAPI springShopOpenAPI() { return new OpenAPI() .info(new Info().title("API文档") .description("SpringBoot3 + MyBatis-Plus项目") .version("v1.0.0")); } }访问地址:http://localhost:8080/swagger-ui.html
9.2 集成Redis缓存
添加依赖:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency>配置application.yml:
spring: redis: host: localhost port: 6379 password: database: 0使用缓存注解:
@Cacheable(value = "user", key = "#id") public User getById(Long id) { return getById(id); }10. 部署与监控
10.1 打包部署
使用Maven打包:
mvn clean package生成的jar包位于target目录下,可以直接运行:
java -jar your-project.jar10.2 集成Actuator监控
添加依赖:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency>配置application.yml:
management: endpoints: web: exposure: include: "*" endpoint: health: show-details: always访问地址:http://localhost:8080/actuator
11. 测试策略
11.1 单元测试
SpringBoot提供了完善的测试支持:
@SpringBootTest class UserServiceTest { @Autowired private UserService userService; @Test void testSave() { User user = new User(); user.setUsername("test"); user.setPassword("123456"); boolean result = userService.save(user); assertTrue(result); } }11.2 集成测试
使用@MybatisPlusTest注解可以快速测试Mapper层:
@MybatisPlusTest class UserMapperTest { @Autowired private UserMapper userMapper; @Test void testSelect() { List<User> users = userMapper.selectList(null); assertFalse(users.isEmpty()); } }12. 安全加固建议
12.1 SQL注入防护
MyBatis-Plus已经内置了SQL注入防护,但还需要注意:
- 不要直接拼接SQL语句
- 使用Wrapper构建查询条件时,避免直接使用用户输入作为条件值
- 对于复杂SQL,使用XML映射文件并确保使用#{}而非${}
12.2 密码安全
用户密码应该加密存储:
@Component public class PasswordEncoder implements org.springframework.security.crypto.password.PasswordEncoder { @Override public String encode(CharSequence rawPassword) { return DigestUtils.md5DigestAsHex(rawPassword.toString().getBytes()); } @Override public boolean matches(CharSequence rawPassword, String encodedPassword) { return encodedPassword.equals(encode(rawPassword)); } }13. 项目优化方向
13.1 多数据源配置
对于需要连接多个数据库的场景:
- 添加依赖:
<dependency> <groupId>com.baomidou</groupId> <artifactId>dynamic-datasource-spring-boot-starter</artifactId> <version>3.6.1</version> </dependency>- 配置多数据源:
spring: datasource: dynamic: primary: master datasource: master: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/master_db username: root password: 123456 slave: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/slave_db username: root password: 123456- 使用@DS注解切换数据源:
@Service @DS("slave") // 默认使用slave数据源 public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService { @DS("master") // 这个方法使用master数据源 public boolean save(User user) { return super.save(user); } }13.2 分布式ID生成
在分布式系统中,可以使用MyBatis-Plus的分布式ID生成策略:
@TableId(type = IdType.ASSIGN_ID) // 使用雪花算法 private Long id;或者自定义ID生成器:
@Bean public IdentifierGenerator idGenerator() { return entity -> { // 实现你的分布式ID生成逻辑 return YourIdGenerator.generate(); }; }14. 常见业务场景实现
14.1 条件查询
使用QueryWrapper构建复杂查询:
QueryWrapper<User> wrapper = new QueryWrapper<>(); wrapper.like("username", "张") .between("age", 20, 30) .orderByDesc("create_time"); List<User> users = userMapper.selectList(wrapper);14.2 乐观锁
- 添加版本号字段:
@Version private Integer version;- 配置乐观锁插件:
@Bean public MybatisPlusInterceptor mybatisPlusInterceptor() { MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor()); return interceptor; }14.3 数据权限控制
通过自定义拦截器实现数据权限过滤:
public class DataPermissionInterceptor implements InnerInterceptor { @Override public void beforeQuery(Executor executor, MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) { // 实现数据权限过滤逻辑 } }15. 项目升级与维护
15.1 版本升级建议
- SpringBoot版本:建议跟随官方发布的最新稳定版,但要注意兼容性
- MyBatis-Plus版本:保持与SpringBoot版本的兼容,参考官方文档
- 数据库驱动:MySQL驱动建议使用8.0+版本
15.2 数据库迁移
对于表结构变更,建议使用Flyway或Liquibase:
- 添加Flyway依赖:
<dependency> <groupId>org.flywaydb</groupId> <artifactId>flyway-core</artifactId> </dependency>- 在resources/db/migration目录下创建迁移脚本:
V1__Initial_schema.sql V2__Add_user_table.sql16. 开发效率提升技巧
16.1 代码模板
在IDEA中配置Live Templates,快速生成常用代码:
- 例如配置"mpc"生成:
@RestController @RequestMapping("/api/$ENTITY$") public class ${ENTITY}Controller { @Autowired private ${ENTITY}Service ${entity}Service; $END$ }16.2 热部署
添加devtools依赖实现热部署:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency>在IDEA中开启自动编译:
- Settings → Build → Compiler → 勾选Build project automatically
- Ctrl+Shift+A → 搜索Registry → 勾选compiler.automake.allow.when.app.running
17. 项目文档编写
17.1 API文档
除了Swagger,还可以使用Postman生成API文档:
- 在Postman中设计好API
- 使用"Publish Docs"功能生成在线文档
- 可以设置访问权限和版本控制
17.2 数据库文档
使用screw工具生成数据库文档:
- 添加依赖:
<dependency> <groupId>cn.smallbun.screw</groupId> <artifactId>screw-core</artifactId> <version>1.0.5</version> </dependency>- 编写配置类:
@Configuration public class ScrewConfig { @Bean public HikariConfig hikariConfig() { HikariConfig config = new HikariConfig(); config.setDriverClassName("com.mysql.cj.jdbc.Driver"); config.setJdbcUrl("jdbc:mysql://localhost:3306/your_db"); config.setUsername("root"); config.setPassword("123456"); return config; } @Bean public DocumentationEngine documentationEngine() { return DocumentationEngine.builder() .dataSource(new HikariDataSource(hikariConfig())) .engineConfig(EngineConfig.builder() .fileOutputDir("docs") .openOutputDir(true) .build()) .produceConfig(ProcessConfig.builder() .build()) .build(); } }18. 团队协作规范
18.1 代码风格统一
- 使用editorconfig文件:
root = true [*] charset = utf-8 indent_style = space indent_size = 4 end_of_line = lf insert_final_newline = true trim_trailing_whitespace = true- 使用checkstyle插件进行代码检查
18.2 Git分支策略
推荐使用Git Flow工作流:
- master:生产环境代码
- develop:开发分支
- feature/xxx:功能分支
- release/xxx:发布分支
- hotfix/xxx:热修复分支
19. 性能监控与调优
19.1 集成Prometheus
- 添加依赖:
<dependency> <groupId>io.micrometer</groupId> <artifactId>micrometer-registry-prometheus</artifactId> </dependency>- 配置application.yml:
management: endpoints: web: exposure: include: prometheus,health,info metrics: tags: application: ${spring.application.name}19.2 性能分析工具
- Arthas:阿里开源的Java诊断工具
- VisualVM:JDK自带的性能分析工具
- JProfiler:商业性能分析工具
20. 容器化部署
20.1 Dockerfile配置
FROM openjdk:17-jdk-slim VOLUME /tmp ARG JAR_FILE=target/*.jar COPY ${JAR_FILE} app.jar ENTRYPOINT ["java","-jar","/app.jar"]构建并运行:
docker build -t springboot-app . docker run -p 8080:8080 -d springboot-app20.2 Kubernetes部署
- 创建deployment.yaml:
apiVersion: apps/v1 kind: Deployment metadata: name: springboot-app spec: replicas: 3 selector: matchLabels: app: springboot-app template: metadata: labels: app: springboot-app spec: containers: - name: app image: springboot-app ports: - containerPort: 8080- 创建service.yaml:
apiVersion: v1 kind: Service metadata: name: springboot-app spec: selector: app: springboot-app ports: - protocol: TCP port: 80 targetPort: 8080 type: LoadBalancer21. 持续集成与交付
21.1 GitHub Actions配置
创建.github/workflows/build.yml:
name: Java CI on: [push] jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - name: Set up JDK 17 uses: actions/setup-java@v2 with: java-version: '17' distribution: 'temurin' - name: Build with Maven run: mvn -B package --file pom.xml - name: Build Docker image run: docker build -t springboot-app .21.2 Jenkins流水线
创建Jenkinsfile:
pipeline { agent any stages { stage('Build') { steps { sh 'mvn clean package' } } stage('Test') { steps { sh 'mvn test' } } stage('Deploy') { steps { sh 'docker build -t springboot-app .' sh 'docker-compose up -d' } } } }22. 项目实战建议
22.1 从小项目开始
建议初学者从以下小型项目开始实践:
- 博客系统:用户、文章、评论等基础功能
- TODO应用:任务管理、分类、优先级
- 库存管理系统:产品、分类、入库出库记录
22.2 逐步添加复杂功能
在基础CRUD实现后,可以逐步添加:
- 权限控制(Spring Security)
- 文件上传(本地存储或OSS)
- 消息队列(RabbitMQ/Kafka)
- 分布式事务(Seata)
- 微服务架构(Spring Cloud)
23. 学习资源推荐
23.1 官方文档
- Spring Boot官方文档
- MyBatis-Plus官方文档
- MySQL官方文档
23.2 推荐书籍
- 《Spring Boot实战》
- 《MyBatis技术内幕》
- 《Java持久化技术详解》
23.3 在线课程
- Spring官方教程
- 慕课网相关实战课程
- B站技术UP主分享
24. 社区与支持
24.1 中文社区
- MyBatis-Plus官方QQ群
- Spring中国社区
- V2EX等技术论坛
24.2 问题排查
遇到问题时:
- 首先查看官方文档和GitHub Issues
- 在Stack Overflow搜索相关问题
- 在技术社区提问(注意提供详细上下文)
25. 未来技术演进
虽然本文基于SpringBoot3和MyBatis-Plus当前稳定版编写,但技术总是在不断发展。建议关注:
- GraalVM原生镜像:SpringBoot3的重要新特性
- 响应式编程:WebFlux与R2DBC的组合
- 云原生趋势:Service Mesh、Serverless等新技术
在实际项目技术选型时,需要平衡新技术的优势与团队的熟悉程度,避免盲目追求最新技术而引入不必要的复杂度。