1. 项目概述
Spring Boot 4.0.2与MyBatis-Plus 3.5.5的组合堪称Java后端开发的"黄金搭档"。作为一名长期奋战在CRUD战场的老兵,我深知重复编码的痛苦——每次新项目都要重写那些几乎相同的增删改查代码,既浪费时间又容易出错。直到遇见MyBatis-Plus,这个基于MyBatis的增强工具包,才真正让我从这种低效劳动中解放出来。
这个组合特别适合:
- 需要快速开发的中小型项目
- 团队中Java基础参差不齐的情况
- 需要保证代码质量但时间紧迫的场景
- 需要灵活应对需求变更的项目
2. 环境搭建与配置
2.1 项目初始化
使用Spring Initializr创建项目时,我推荐选择以下依赖:
- Spring Web
- Lombok
- MySQL Driver
- MyBatis-Plus
pom.xml关键依赖配置:
<dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.5.5</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <version>4.0.2</version> </dependency>2.2 数据库配置
application.yml配置示例:
spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/mp_demo?useSSL=false&serverTimezone=UTC username: root password: 123456 mybatis-plus: configuration: log-impl: org.apache.ibatis.logging.stdout.StdOutImpl # 开启SQL日志注意:MySQL 8.0+必须指定serverTimezone参数,否则会报时区错误
3. 核心功能实现
3.1 实体类设计
User.java示例:
@Data @TableName("sys_user") public class User { @TableId(type = IdType.AUTO) private Long id; @TableField("user_name") private String username; private String password; private Integer age; private String email; @TableField(fill = FieldFill.INSERT) private LocalDateTime createTime; @TableField(fill = FieldFill.INSERT_UPDATE) private LocalDateTime updateTime; }关键注解说明:
@TableName:指定表名@TableId:主键策略@TableField:字段映射与自动填充
3.2 Mapper接口
UserMapper.java简单到不可思议:
@Mapper public interface UserMapper extends BaseMapper<User> { // 无需任何方法声明 }BaseMapper提供的CRUD方法:
- 插入:int insert(T entity)
- 删除:int deleteById(Serializable id)
- 更新:int updateById(T entity)
- 查询:T selectById(Serializable id)
3.3 Service层封装
虽然可以直接使用Mapper,但我建议添加Service层:
@Service public class UserService { @Autowired private UserMapper userMapper; public User getById(Long id) { return userMapper.selectById(id); } public boolean saveUser(User user) { return userMapper.insert(user) > 0; } // 其他CRUD方法... }4. 高级特性应用
4.1 条件构造器
QueryWrapper使用示例:
QueryWrapper<User> wrapper = new QueryWrapper<>(); wrapper.like("user_name", "张") .between("age", 20, 30) .isNotNull("email"); List<User> users = userMapper.selectList(wrapper);Lambda写法更安全:
LambdaQueryWrapper<User> lambdaWrapper = Wrappers.lambdaQuery(); lambdaWrapper.like(User::getUsername, "张") .lt(User::getAge, 30);4.2 分页查询
配置分页插件:
@Configuration public class MybatisPlusConfig { @Bean public MybatisPlusInterceptor mybatisPlusInterceptor() { MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); interceptor.addInnerInterceptor(new PaginationInnerInterceptor()); return interceptor; } }分页查询示例:
Page<User> page = new Page<>(1, 10); LambdaQueryWrapper<User> wrapper = Wrappers.lambdaQuery(); wrapper.orderByDesc(User::getCreateTime); IPage<User> userPage = userMapper.selectPage(page, wrapper);4.3 自动填充
实现MetaObjectHandler:
@Component public class MyMetaObjectHandler implements MetaObjectHandler { @Override public void insertFill(MetaObject metaObject) { this.strictInsertFill(metaObject, "createTime", LocalDateTime.class, LocalDateTime.now()); } @Override public void updateFill(MetaObject metaObject) { this.strictUpdateFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now()); } }5. 实战技巧与避坑指南
5.1 性能优化建议
- 批量操作:
List<User> userList = new ArrayList<>(); // 添加数据... boolean success = userService.saveBatch(userList, 1000); // 每批1000条- 逻辑删除配置:
mybatis-plus: global-config: db-config: logic-delete-field: deleted # 逻辑删除字段名 logic-delete-value: 1 # 逻辑已删除值 logic-not-delete-value: 0 # 逻辑未删除值5.2 常见问题解决
- 字段映射问题:
- 数据库字段:user_name
- 实体字段:username 解决方案:
@TableField("user_name") private String username;- 主键ID回填:
User user = new User(); userMapper.insert(user); // 插入后自动回填ID Long id = user.getId();- 版本冲突解决: 如果遇到MyBatis与MyBatis-Plus版本冲突,可以排除MyBatis自带版本:
<dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <exclusions> <exclusion> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> </exclusion> </exclusions> </dependency>6. 项目实战演示
6.1 RESTful接口实现
UserController示例:
@RestController @RequestMapping("/users") 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)); } @GetMapping("/page") public Result<IPage<User>> page(@RequestParam(defaultValue = "1") int current, @RequestParam(defaultValue = "10") int size) { return Result.success(userService.page(new Page<>(current, size))); } }6.2 复杂查询示例
多表联查解决方案:
@Select("SELECT u.*, d.dept_name FROM sys_user u LEFT JOIN sys_dept d ON u.dept_id = d.id") List<UserVO> selectUserWithDept();提示:复杂SQL建议仍使用XML或注解方式,MyBatis-Plus主要简化单表操作
7. 扩展与进阶
7.1 代码生成器
MyBatis-Plus提供了强大的代码生成器:
FastAutoGenerator.create("jdbc:mysql://localhost:3306/mp_demo", "root", "123456") .globalConfig(builder -> builder.author("dev").outputDir("D://code")) .packageConfig(builder -> builder.parent("com.example.mp")) .strategyConfig(builder -> builder.addInclude("sys_user")) .execute();7.2 多数据源配置
使用dynamic-datasource-spring-boot-starter:
spring: datasource: dynamic: primary: master datasource: master: url: jdbc:mysql://localhost:3306/master username: root password: 123456 slave: url: jdbc:mysql://localhost:3306/slave username: root password: 123456使用@DS注解切换数据源:
@Service @DS("slave") public class UserServiceImpl implements UserService { // 查询方法默认使用slave数据源 @DS("master") public void addUser(User user) { // 此方法使用master数据源 } }在实际项目中,我发现MyBatis-Plus最适合中小型项目的快速开发,但当系统复杂度增加到需要大量复杂SQL和存储过程时,可能需要回归原生MyBatis的灵活性。不过对于80%的常规CRUD操作,这个组合确实能提升至少50%的开发效率。