MybatisPlus
初识MybatisPlus
MybatisPlus的特点
- 可以对现有工程只做增强不做改变,引入MybatisPlus后Mybatis的代码依旧可以使用
- 方便快捷实现对单表的增删改查
- 功能丰富 例如 代码生成,自动分页,自动填充
使用MybatisPlus
- 引入MybatisPlus
1
2
3
4
5<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-spring-boot3-starter</artifactId>
<version>3.5.7</version>
</dependency> - 自定义的Mapper 继承MybatisPlus提供的BaseMapper
注意:BaseMapper需要指定实体类型1
2
3public interface UserMapper extends BaseMapper<User> {
}MybatisPlus的常用注解
- @TableName : 用于指定表名
当实体类名和数据库表名不一致的时候使用 - @TableId :用于指定表中的主键字段信息
可以指定主键的憎长类型,共有三种,(AUTO)数据库自增长,(INPUT)get方式输入,(ASSIGN_ID)自带的雪花算法
若不指定则默认为yaml配置的方式 - @TableFieId :用于指定表中的普通字段信息
直接上图
MybatisPlus的配置

MybatisPlus的条件构造器
MybatisPlus提供了三种条件构造器
- QueryWrapper
提供了很多关于查询的条件方法,方法很多就不一一展示了,通过一个示例简单说明一下
将图中sql可简化为1
2
3
4
5QueryWrapper queryWrapper = new QueryWrapper<User>()
.select("id","username","info","balance").like("username","o")
.gt("blance",1000);
List<User> list = userMapper.selectList(queryWrapper); - UpdateWrapper
提供了更新的条件方法
1
2
3
4UpdateWrapper<User> updateWrapper = new UpdateWrapper<User>()
.setSql("balance =balance - 200").in("id","1,2,4");
userMapper.update(null,updateWrapper);
IService接口

MybatisPuls提供了IService接口更帮助我们实现对单表的增删改查
使用IService接口需要两步
- 自定义的XXXService接口去继承Iservice接口
- XXXService的实现类XXXServiceImpl实现Service的同时也要继承IService的实现类
注意!! XXXServiceImpl继承IService的实现类的时候需要给IService的实现类两个参数 - 第一个参数所对应的Mapper接口,因为在IService的实现类里面是需要引入对应的mapper
即IService里面很多方法底层还是通过MybatisPuls提供的Mapper的方法实现 - 第二个参数为对应的实体对象
例如1
2
3
4
5
6
7
8public interface UserService extends IService<User>{
}
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService{
}IService的应用
IService提供更多的方法供我们使用,同样这么多方法也就不一一介绍了
值得一提的是IService提供的批量插入方法saveBeach方法
假设我们需要像数据库中插入10000条数据 - 单条数据插入最后耗时10180毫秒
1
2
3
4
5
6
7
8
9
10
11public void test1() {
long a =System.currentTimeMillis();
for (int i = 0; i <10000 ; i++) {
Test1 test =new Test1();
test.setUser(i);
test.setName("test"+i);
tsetService.save(test);
}
long b =System.currentTimeMillis();
System.out.println(b-a);
} - 批量插入最后耗时264毫秒,显著提升了50倍速度!!!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15public void test2() {
long a =System.currentTimeMillis();
List<Test1> list =new ArrayList<>();
for (int i = 0; i <10000 ; i++) {
Test1 test =new Test1();
test.setUser(i);
test.setName("test"+i);
list.add(test);
if (list.size()==100) {
tsetService.saveBatch(list);
}
}
long b =System.currentTimeMillis();
System.out.println(b-a);
}
当然啦这还不是最快的 - MYSQL的rewriteBatchedStatements=true
在配置数据库的url后面添加rewriteBatchedStatements=true 即可
代码与上面代码相同不变
最后耗时202毫秒,由于我直插入了10000条数据所以性能不明显,数据越多明显越大
最后再来说一下rewriteBatchedStatements=true的作用
- 如果不加,我们操作会是将一千条数据封装到list中,由list传入数据库,然后每一条数据执行一次insert语句
所以提升速度的原因是减少了连接数据库的次数 - 加上rewriteBatchedStatements=true后,list传入后数据库只需要执行一次insert语句,因为者一千条数据会进行拼接
DB静态工具
介绍之前先看几个需求,前置条件,用户和地址是两个表,用外键链接
根据已经学习到的知识,如果我们想解决第一个问题就需要
- 在UserService中不仅仅调用自己的IService提供的方法,也需要调用AddressService
(当然啦也可以调用AddressMapper) - 解决第三个问题呢就需要在AddressService中调用UserService,这样互相调用的话,业务复杂
很多个Service层或者Mapper互相调用很大可能会造成循环依赖
为了解决循环依赖问题,MybatisPlus提供了DB静态工具(注意:需要3.5.0版本以上) - DB提供了和IService几乎一摸一样的方法 不过在调用DB的时候需要将所对应的实体类传入
利用DB解决问题1
JOSN处理器
作用:如果数据库表中有字段类型为JOSN时,可以使用Mybatis提供的JOSN处理器,简化开发
普通方法我会用一个String类型的变量去接收 表中JOSN类型的字段,但是这样后续业务处理比较麻烦
使用JSON处理器可以解决这个问题,需要三步
- 定义一个表中JOSN类型字段锁对应的实体类,用这个实体类类型的变量去接收
- 同时需要使用@TableFiled中添加JOSN处理器 即typeHandler=JacksonTypeHandler.class
- 在@TableName中加上 autoResultMap =true 返回映射

MybatisPlus的分页功能
MybatisPlus提供了很多拓展功能其中较为常用的就是分页功能
分页功能的配置类
1
2
3
4
5
6
7
8
9
10
11
12
13@Configuration
public class MybatisConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor(){
// 1.初始化核心插件
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
// 2.添加分更插件 和指定数据库类型
PaginationInnerInterceptor pageInterceptor = new PaginationInnerInterceptor(DbType.MysOL)
pageInterceptor.setMaxLimit(1000L);//设置分页上限
interceptor.addInnerInterceptor(pagenterceptor);
return interceptor;
}
}个人理解:先new一个MybatisPlus的拦截器对象,在new一个分页对象并设置初始值添加到拦截器中
分页功能的基本使用
- 这是简单封装了一个PageVO,用于处理分页查询后的数据,方便返回前端
1
2
3
4
5pubilc class PageVO<T>{
public Ingter pages;
public Ingter total;
public List<T> list
} - 简单使用以上就是一个分页查询用户的简单例子
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22public PageVO<UserVO> queryUsersPage(UserQuery query){
String name = query.getName();
Integer status = query.getstatus();
//1.构建分页条件
// 1.1.分页条件 Page.of()需要两个参数 一个当前的页数,一个每页查询的数据量
Page<User>page = Page.of(query.getPageNo(),query.getPagesize());
// 1.2.排序条件
page.addorder(new orderItem(query.getSortBy(), query.getIsAsc()));
//1 2.分页查询
Page<User> p=lambdaQuery()
.like( condition: name != null, User::getUsername, name)
.eq( condition: status != null, User::getstatus, status)
.page(page);
// 处理数据
PageVO(UserVO) pagevo =new PageVO()
pagevo.setPages(p.getPages);
pagevo.setTotal(p.getTotal);
List<User> list = p.getRecords();
List<UserVO> vo= BeanUtil.copyToList(list,UserVo.class)
pagevo.setlist(vo);
return pagevo;
}
在实际功能中 构建分页条件 排序条件 处理数据 这三个步骤在多次分页中代码基本相同
所以其实可以将这几部分代码抽取成三个工具类,使用到这几个步骤的时候直接调用对应的工具类
- 这是简单封装了一个PageVO,用于处理分页查询后的数据,方便返回前端
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Little Monste'Blog!
评论




