一、MyBatis与MyBatis-Plus的核心差异
特性 | MyBatis | MyBatis-Plus |
---|---|---|
SQL编写方式 | 需手动编写SQL(XML/注解) | 内置通用Mapper,支持QueryWrapper动态构建SQL |
代码生成 | 需第三方工具(如MyBatis Generator) | 内置代码生成器(AutoGenerator ) |
字段变更维护 | 修改字段需重写所有相关SQL | 仅需更新实体类,Wrapper自动适配 |
CRUD实现 | 手动实现增删改查 | 继承BaseMapper 即可获得通用方法 |
复杂SQL支持 | 灵活编写复杂SQL | 需结合XML或自定义SQL注入 |
二、字段变更场景对比:手写SQL vs QueryWrapper
1. MyBatis手写SQL痛点示例
场景:用户表user
新增字段age
需修改的XML内容:
<!-- 原insert语句 -->
<insert id="insertUser">
INSERT INTO user (name, email)
VALUES (#{name}, #{email})
</insert>
<!-- 修改后 -->
<insert id="insertUser">
INSERT INTO user (name, email, age)
VALUES (#{name}, #{email}, #{age})
</insert>
<!-- 同时需修改update、select等所有涉及字段的SQL -->
缺点:
-
修改多个XML节点,易遗漏或出错
-
字段频繁变更时维护成本高
2. MyBatis-Plus的QueryWrapper优化方案
场景:同样新增字段age
操作步骤:
-
实体类更新:在
User
类中添加age
字段 -
插入数据:直接使用
BaseMapper
的insert
方法 -
条件查询:通过Wrapper动态构建条件
// 插入数据(无需修改SQL) User user = new User(); user.setName("John"); user.setEmail("john@example.com"); user.setAge(25); // 新增字段 userMapper.insert(user); // 查询条件构建 QueryWrapper<User> wrapper = new QueryWrapper<>(); wrapper.eq("age", 25) // 直接使用新字段 .like("name", "J"); List<User> users = userMapper.selectList(wrapper);
优点:
-
无需修改任何XML文件
-
字段名通过Lambda表达式引用(防硬编码)
wrapper.eq(User::getAge, 25); // 更安全的写法
三、MyBatis-Plus的核心优势
1、动态SQL构建
-
通过
QueryWrapper
、UpdateWrapper
等链式调用方法,避免SQL拼接错误。 -
示例:多条件动态查询
wrapper.gt("create_time", startDate)
.lt("status", 3)
.orderByDesc("id");
2、通用CRUD方法
-
继承
BaseMapper
后自动获得selectById
、update
等方法,减少重复代码。 -
支持批量操作:
insertBatchSomeColumn
(需配置SQL注入器)。
3、代码生成器
-
一键生成Entity、Mapper、Service层代码,适应表结构变更。
AutoGenerator generator = new AutoGenerator();
generator.setGlobalConfig(config); // 配置数据源、包路径等
generator.execute();
4、乐观锁与逻辑删除
-
注解
@Version
实现乐观锁,@TableLogic
实现逻辑删除,简化业务逻辑。
四、MyBatis的适用场景
-
复杂SQL需求
多表关联查询、存储过程调用等场景需灵活手写SQL。 -
历史项目维护
已有大量MyBatis XML的项目,迁移成本较高。 -
高度定制化SQL
需要精细控制SQL执行计划或数据库特性(如Oracle的ROWNUM)。
五、选型建议
项目类型 | 推荐框架 | 理由 |
---|---|---|
快速开发新项目 | MyBatis-Plus | 减少CRUD代码量,提升开发效率 |
频繁字段变更的业务系统 | MyBatis-Plus | 避免因字段增减导致的SQL维护负担 |
复杂查询为主的系统 | MyBatis | 灵活控制SQL细节 |
混合型项目 | MyBatis+MyBatis-Plus | 通用操作用Plus,复杂SQL保留手写 |
六、实战对比案例
需求:根据状态分页查询用户,并按注册时间排序
-
MyBatis实现:
<select id="selectByPage" resultType="User">
SELECT * FROM user
WHERE status = #{status}
ORDER BY create_time DESC
LIMIT #{offset}, #{size}
</select>
字段变更时需修改SELECT字段列表。
-
MyBatis-Plus实现:
Page<User> page = new Page<>(current, size);
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.eq("status", status)
.orderByDesc("create_time");
userMapper.selectPage(page, wrapper);
-
字段变更仅需更新实体类,无需调整SQL。
七、总结
-
MyBatis-Plus核心价值:通过自动化CRUD和动态SQL,将开发者从重复劳动中解放。
-
MyBatis不可替代性:在复杂SQL场景中仍是首选方案。
-
混合使用策略:80%的简单操作使用MyBatis-Plus,20%的复杂查询保留MyBatis XML。