MyBatis Plus指南
一、概述
1.MyBatis Plus 是什么?
MyBatis Plus(简称 MP)是一个基于 MyBatis 的增强工具,它简化了 MyBatis 的开发流程,提供了更强大、更便捷的功能,使得开发人员能够更加高效地进行数据库操作和开发。MyBatis Plus 提供了一系列的注解和方法,可以帮助开发人员快速构建和执行 SQL 语句,减少了手写 SQL 的工作量。
2.MyBatis Plus 的特点和优势
3.MyBatis Plus 的适用场景
- 中小型项目:MyBatis Plus 简化了 MyBatis 的开发流程,提供了更强大、更便捷的功能,适用于中小型项目的开发。
- 数据库操作频繁的项目:MyBatis Plus 提供了强大的 CRUD 功能和分页查询功能,适用于数据库操作频繁的项目。
- 多表关联查询较多的项目:MyBatis Plus 提供了多表关联查询的功能,可以方便地进行多表关联查询,适用于多表关联查询较多的项目。
- 需要快速开发的项目:MyBatis Plus 提供了代码生成器的功能,可以根据数据库表结构自动生成代码,适用于需要快速开发的项目。
- 需要乐观锁和逻辑删除功能的项目:MyBatis Plus 内置了乐观锁和逻辑删除的功能,适用于需要进行数据并发控制和逻辑删除的项目。 总之,MyBatis Plus 是一个功能强大、易于使用的数据库操作工具,适用于各种类型的项目开发。
二、快速入门
三、实体类的常用注解配置
1.@TableName 注解
用于指定实体类对应的数据库表名。可以在实体类上使用该注解,通过value属性指定表名。
2.@TableField 注解
用于指定实体类中字段与数据库表中字段的映射关系。可以在实体类的属性上使用该注解,通过value属性指定字段名。
3.@TableId 注解
用于指定实体类中的主键字段。可以在实体类的属性上使用该注解,通过value属性指定主键字段名。
4.@Version 注解
用于实现乐观锁机制。可以在实体类的属性上使用该注解,表示该字段用于记录数据版本号 。
5.@TableLogic 注解
用于实现逻辑删除功能。可以在实体类的属性上使用该注解,表示该字段用于标记逻辑删除状态。
6.@TableIndex 注解
用于指定数据库表的索引。可以在实体类上使用该注解,通过value属性指定索引名,通过columns属性指定索引的字段。
四、掌握CRUD操作和条件构造器的使用
1.什么是CRUD?基本的 CRUD 的使用
CRUD是指对数据进行增加(Create)、查询(Retrieve)、更新(Update)和删除(Delete)等操作的一种常见的数据操作方式。
- Create:创建数据,即向数据库中插入新的记录。
- Retrieve:查询数据,即从数据库中获取符合条件的记录。
- Update:更新数据,即修改数据库中已有的记录。
- Delete:删除数据,即从数据库中删除指定的记录
而通过使用MyBatis-Plus的模板相比mybatis,可以简化CRUD操作的编写,提高开发效率,
新增:
@PostMapping("save")
public Boolean add(@RequestBody User user){
return userService.save(user);
}
删除
@DeleteMapping("delete")
public Boolean delete(int id){
return userService.removeById(id);
}
修改(如果数据存在则为修改,如果数据不存在则为新增)
@PostMapping("saveOrUpdate")
public Boolean update(@RequestBody User user){
return userService.saveOrUpdate(user);
}
查询
@GetMapping("list")
public List<User> list(){
return userService.list();
}
2.条件构造器
1.QueryWrapper
使用QueryWrapper构建查询条件,通过eq方法添加年龄等于20的条件,通过like方法添加姓名包含"Tom"的条件,通过orderByDesc方法按照创建时间降序排序,然后使用selectList方法执行查询操作。
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("age", 20)
.like("name", "Tom")
.orderByDesc("create_time");
List<User> userList = userMapper.selectList(queryWrapper);
2.LambdaQueryWrapper
使用LambdaQueryWrapper构建查询条件,通过eq方法使用Lambda表达式添加年龄等于20的条件,通过like方法使用Lambda表达式添加姓名包含"Tom"的条件,通过orderByDesc方法使用Lambda表达式按照创建时间降序排序,然后使用selectList方法执行查询操作。
LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.eq(User::getAge, 20)
.like(User::getName, "Tom")
.orderByDesc(User::getCreateTime);
List<User> userList = userMapper.selectList(lambdaQueryWrapper);
3.UpdateWrapper
使用UpdateWrapper构建更新条件,通过set方法设置年龄为25,通过eq方法添加姓名等于"Tom"的条件,然后使用update方法执行更新操作。
UpdateWrapper<User> updateWrapper = new UpdateWrapper<>();
updateWrapper.set("age", 25)
.eq("name", "Tom");
int rows = userMapper.update(null, updateWrapper);
4.LambdaUpdateWrapper
使用LambdaUpdateWrapper构建更新条件,通过set方法使用Lambda表达式设置年龄为25,通过eq方法使用Lambda表达式添加姓名等于"Tom"的条件,然后使用update方法执行更新操作
LambdaUpdateWrapper<User> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
lambdaUpdateWrapper.set(User::getAge, 25)
.eq(User::getName, "Tom");
int rows = userMapper.update(null, lambdaUpdateWrapper);
2.分页模糊查询的实现
@PostMapping("listPage")
public List<User> liseUserPage(@RequestBody PageParam query){
HashMap param = query.getParam();
String name= (String)param.get("username");
Page<User> page = new Page();
page.setCurrent(query.getPageNum());
page.setSize(query.getPageSize());
LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper();
lambdaQueryWrapper.like(User::getUsername,name);
IPage result = userService.page(page,lambdaQueryWrapper);
return result.getRecords();
}
3.自定义 SQL 的执行
这里用分页模糊查询作为例子
controller层
@PostMapping("listPageCC")
public List<User> liseUserPageCC(@RequestBody PageParam query){
HashMap param = query.getParam();
String name= (String)param.get("username");
Page<User> page = new Page();
page.setCurrent(query.getPageNum());
page.setSize(query.getPageSize());
LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper();
lambdaQueryWrapper.like(User::getUsername,name);
IPage result = userService.pageCC(page,lambdaQueryWrapper);
return result.getRecords();
}
service层
小扩展:
Service是一种设计模式,用于将业务逻辑与数据访问逻辑分离。Service层负责处理业务逻辑,包括数据的处理、转换、验证等。它与具体的数据访问方式(如数据库、文件等)无关,使得业务逻辑更加、可复用和可测试。
Serviceimpl(Service接口)定义了业务逻辑的方法,而Service实现类则实现了这些方法,具体实现了业务逻辑的处理。
为什么要这么做呢?
- 分离关注点:将业务逻辑与数据访问逻辑分离,使得代码更加清晰、可维护和可测试。
- 提高复用性:将业务逻辑封装在Service中,可以在不同的场景下复用。
- 降低耦合性:Service层与具体的数据访问方式解耦,使得业务逻辑不依赖于具体的数据访问实现。
- 提供事务管理:Service层可以管理事务,确保业务操作的一致性和完整性。
service
public interface UserService extends IService<User> {
IPage pageCC(IPage<User> page, Wrapper wrapper);
}
serviceimpl
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
@Resource
private UserMapper userMapper;
@Override
public IPage pageCC(IPage<User> page, Wrapper wrapper) {
return userMapper.pageCC(page,wrapper);
}
}
mapper层
@Mapper
public interface UserMapper extends BaseMapper<User> {
IPage pageCC(IPage<User> page,@Param(Constants.WRAPPER) Wrapper wrapper);
}
sql语句
${ew.customSqlSegment}是MyBatis Plus框架中的一个占位符,用于动态生成SQL语句的条件部分。在MyBatis Plus中,使用Wrapper对象来构建查询条件,ew就是Wrapper对象的实例。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.cqgcxy.mapper.UserMapper">
<!-- 自定义分页模糊查询-->
<select id="pageCC" resultType="com.cqgcxy.pojo.User">
select * from user ${ew.customSqlSegment}
</select>
</mapper>
五、代码生成器的使用
六、MyBatis Plus的优缺点
优点
- 简化开发:MyBatis Plus提供了很多便捷的API和工具,可以大大简化数据库操作的开发工作。例如,通过继承BaseMapper接口,可以直接使用常用的增删改查方法,无需手动编写SQL语句。
- 提高效率:MyBatis Plus提供了代码生成器,可以根据数据库表结构自动生成实体类、Mapper接口和XML映射文件,减少了手动编写重复代码的工作量,提高了开发效率。
- 强大的查询功能:MyBatis Plus提供了丰富的查询方法和条件构造器,可以灵活地进行复杂的查询操作。例如,可以通过Lambda表达式来构建查询条件,使得查询语句更加简洁和易读。
- 支持分页查询:MyBatis Plus内置了分页插件,可以方便地进行分页查询操作,减少了手动编写分页逻辑的工作量。
- 支持多种数据库:MyBatis Plus支持多种主流的关系型数据库,如MySQL、Oracle、SQL Server等,可以在不同的数据库之间无缝切换。
不足
- 灵活性受限:MyBatis Plus提供了很多便捷的功能和API,但有时候可能会受到框架的,无法满足一些特定的需求。在某些复杂的场景下,可能需要手动编写SQL语句或者自定义插件来实现。
- 过度封装:MyBatis Plus对MyBatis进行了封装和扩展,提供了更高层次的抽象和封装,但有时候可能会导致开发者对底层的SQL执行细节不够了解,难以进行性能优化和调优。