MyBatis与MyBatis-Plus深度分析
一、MyBatis原理与基础
1. MyBatis核心原理
MyBatis是一个半自动ORM框架,主要原理包括:
- SQL与代码分离:通过XML或注解配置SQL语句
- 动态SQL:提供if、choose、foreach等标签实现动态SQL
- 结果集映射:将数据库结果集自动映射到Java对象
- 一级/二级缓存:提供缓存机制提高性能
2. MyBatis基础知识点
核心组件:
- SqlSessionFactory:创建SqlSession的工厂
- SqlSession:执行SQL的核心接口
- Mapper接口:定义数据库操作方法
- Mapper XML:编写SQL语句的配置文件
关键特性:
- 参数映射(#{}, ${})
- 结果映射(resultMap)
- 动态SQL标签
- 插件机制
3. MyBatis简单案例
// Mapper接口
public interface UserMapper {@Select("SELECT * FROM users WHERE id = #{id}")User getUserById(int id);@Insert("INSERT INTO users(name, email) VALUES(#{name}, #{email})")@Options(useGeneratedKeys = true, keyProperty = "id")void insertUser(User user);
}// 实体类
public class User {private Integer id;private String name;private String email;// getters/setters
}// 使用示例
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
try (SqlSession session = sqlSessionFactory.openSession()) {UserMapper mapper = session.getMapper(UserMapper.class);User user = mapper.getUserById(1);System.out.println(user.getName());
}
二、MyBatis-Plus原理与增强
1. MyBatis-Plus核心原理
MyBatis-Plus在MyBatis基础上增强:
- 自动CRUD:内置通用Mapper,减少基础SQL编写
- 条件构造器:通过Lambda表达式构建查询条件
- 代码生成器:自动生成Entity、Mapper等代码
- 分页插件:简化分页操作
- 性能分析插件:输出SQL执行性能
2. MyBatis-Plus基础知识点
核心特性:
- 通用CRUD操作
- Lambda表达式查询
- 主键策略支持
- 全局配置
- 乐观锁支持
- SQL注入器
与MyBatis主要区别:
特性 | MyBatis | MyBatis-Plus |
---|---|---|
CRUD操作 | 需手动编写 | 内置通用方法 |
条件构造 | 需写SQL | Lambda表达式 |
代码生成 | 需第三方工具 | 内置生成器 |
分页 | 需插件 | 内置分页插件 |
性能分析 | 需配置 | 内置插件 |
3. MyBatis-Plus简单案例
// 实体类
@Data
@TableName("users")
public class User {@TableId(type = IdType.AUTO)private Long id;private String name;private String email;
}// Mapper接口
public interface UserMapper extends BaseMapper<User> {// 已继承基本CRUD方法
}// 服务层
@Service
public class UserService {@Autowiredprivate UserMapper userMapper;public List<User> getUsersByName(String name) {QueryWrapper<User> queryWrapper = new QueryWrapper<>();queryWrapper.lambda().eq(User::getName, name);return userMapper.selectList(queryWrapper);}
}// 使用Lambda查询
List<User> users = userMapper.selectList(Wrappers.<User>lambdaQuery().like(User::getName, "张").gt(User::getAge, 18)
);
三、综合对比与选择建议
1. 适用场景
- MyBatis适用场景:
- 需要精细控制SQL
- 复杂查询和存储过程调用
- 已有MyBatis项目维护
- MyBatis-Plus适用场景:
- 快速开发CRUD功能
- 需要减少样板代码
- 新项目开发
2. 性能考虑
- MyBatis-Plus在简单CRUD上效率更高(减少代码量)
- 复杂SQL场景两者性能相当(最终都转为MyBatis执行)
- MyBatis-Plus的Lambda查询会转换为MyBatis的SQL,无额外性能损耗
3. 综合案例展示
复杂查询+分页案例:
// MyBatis实现
@Select("SELECT * FROM users WHERE name LIKE #{name} AND age > #{age} LIMIT #{offset}, #{size}")
List<User> findUsers(@Param("name") String name, @Param("age") int age,@Param("offset") int offset,@Param("size") int size);// MyBatis-Plus实现
Page<User> page = new Page<>(1, 10); // 第1页,每页10条
LambdaQueryWrapper<User> wrapper = Wrappers.lambdaQuery();
wrapper.like(User::getName, "张").gt(User::getAge, 18);
IPage<User> userPage = userMapper.selectPage(page, wrapper);
动态更新案例:
// MyBatis实现
@Update("<script>" +"UPDATE users " +"<set>" +" <if test='name != null'>name=#{name},</if>" +" <if test='email != null'>email=#{email},</if>" +"</set>" +"WHERE id=#{id}" +"</script>")
void updateUserSelective(User user);// MyBatis-Plus实现
userMapper.update(null, Wrappers.lambdaUpdate(User.class).set(User::getName, "新名字").eq(User::getId, 1));
四、总结
- MyBatis提供更精细的SQL控制,适合复杂场景
- MyBatis-Plus大幅简化CRUD操作,提高开发效率
- 两者可以结合使用,MyBatis-Plus处理简单操作,复杂SQL仍可用原生MyBatis方式
- 新项目推荐使用MyBatis-Plus,可显著减少样板代码
根据项目需求和团队熟悉程度选择合适的框架,大型项目中也可以两者混合使用,兼顾开发效率和灵活性