在使用传统MyBatis框架进行持久层开发时,我们常常需要手写大量重复的XML配置和基础SQL语句。MyBatis-Plus(简称MP)作为MyBatis的增强工具包,通过内置通用Mapper和强大的条件构造器,能显著提升开发效率。本文将带领大家深入了解其核心功能,并通过完整示例演示CRUD操作与查询构建技巧。


1. 基础环境搭建

(Spring Boot + MySQL) 本文技术栈:Spring Boot 2.7.0 + MyBatis-Plus 3.5.3 + MySQL 8.0 + Lombok

1.1 依赖配置

<dependencies>
    <!-- Spring Boot基础依赖 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    
    <!-- MyBatis-Plus核心包 -->
    <dependency>
        <groupId>com.baomidou</groupId>
        <artifactId>mybatis-plus-boot-starter</artifactId>
        <version>3.5.3</version>
    </dependency>

    <!-- MySQL连接驱动 -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <scope>runtime</scope>
    </dependency>

    <!-- Lombok简化实体类 -->
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>
</dependencies>

1.2 实体类定义

@Data
@TableName("sys_user") // 对应数据库表名
public class User {
    @TableId(type = IdType.AUTO) // 主键自增策略
    private Long id;
    private String username;
    private Integer age;
    private String email;
    @TableField("create_time") // 字段映射
    private LocalDateTime createTime;
}

2. CRUD接口实战

2.1 新增操作

// 单个插入
User newUser = new User()
    .setUsername("Alice")
    .setAge(25)
    .setEmail("alice@example.com");
userMapper.insert(newUser); // 返回影响行数

// 批量插入(需要开启SQL注入器)
List<User> users = Arrays.asList(user1, user2, user3);
userMapper.insertBatchSomeColumn(users); // MP 3.5.3+特性

2.2 删除操作

// ID删除
userMapper.deleteById(1L); 

// 条件删除
Map<String, Object> params = new HashMap<>();
params.put("age", 30);
userMapper.deleteByMap(params); // WHERE age = 30

// 逻辑删除(需配置逻辑删除字段)
@TableLogic
private Integer deleted;
userMapper.deleteById(2L); // 实际执行UPDATE操作

3. 条件构造器详解

3.1 QueryWrapper基础查询

// 查询年龄大于25且有邮箱的用户
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.gt("age", 25)
       .isNotNull("email")
       .orderByDesc("create_time");

List<User> users = userMapper.selectList(wrapper);

3.2 Lambda表达式写法

LambdaQueryWrapper<User> lambdaWrapper = new LambdaQueryWrapper<>();
lambdaWrapper.ge(User::getAge, 18)
             .likeRight(User::getUsername, "张") // 张%
             .select(User::getId, User::getUsername); // 字段过滤

List<User> userList = userMapper.selectList(lambdaWrapper);

4. 高级查询技巧

4.1 复杂条件组合

QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.and(qw -> qw.lt("age", 30).or().isNull("email"))
       .apply("date_format(create_time,'%Y-%m-%d') = {0}", "2023-08-01")
       .last("LIMIT 10"); // 慎用last方法

4.2 联表查询实现

QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.inSql("id", "SELECT user_id FROM user_role WHERE role_id = 2");

List<User> adminUsers = userMapper.selectList(wrapper);

5. 技术应用场景

5.1 适用场景

  • 快速原型开发:基础CRUD接口开箱即用
  • 动态查询构建:灵活组装复杂查询条件
  • 多租户系统:配合TenantLineInnerInterceptor实现数据隔离
  • 逻辑删除场景:零成本实现软删除功能

6. 优势与局限性

6.1 核心优势

  • ⚡ 开发效率提升:减少80%基础代码量
  • 🛡️ 安全防护:自动预防SQL注入
  • 📚 学习曲线平缓:API设计符合Java流式编程习惯
  • 🔄 平滑迁移:兼容原生MyBatis特性

6.2 使用注意

  • 复杂SQL建议使用XML方式
  • 避免过度依赖Wrapper对象生成复杂SQL
  • 分页插件需要额外配置
  • 主键策略需要根据DB类型选择

7. 实践总结

在实际项目中使用MyBatis-Plus时,建议遵循以下原则:

  1. 合理划分业务边界,明确哪些场景适合使用Wrapper
  2. 及时清理不再使用的Wrapper对象
  3. 对高频查询建立数据库索引
  4. 保持MP版本更新以获得最新特性支持