MybatisPlus插件功能

1.MybatisPlus提供的插件

1.1 分页插件

MybatisPlus提供了分页的插件,使用MP的分页插件可以简化项目开发中的分页需求.

1.1.1 分页插件的使用

步骤一

首先要在配置类中注册MybatisPlus的核心插件,同时添加分页插件:

1
2
3
4
5
6
7
8
9
10
11
12
@Configuration
public class MybatisConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
// 1.初始化核心插件
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
// 2.添加分页插件
PaginationInnerInterceptor pageInterceptor = new PaginationInnerInterceptor(DbType.MYSQL); pageInterceptor.setMaxLimit(1000L); // 设置分页上限
interceptor.addInnerInterceptor(pageInterceptor);
return interceptor;
}
}

步骤二

完成了配置类后就可以使用分页的API了

1.1.2 编写测试类测试

编写测试类测试

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
/**
* 分页查询测试
*/
@Test
public void testPageQuery(){
int pageNo = 1;
int pageSize = 2;
// 1.准备分页条件
Page<User> page = Page.of(pageNo, pageSize);
// 1.1准备排序条件 true 为升序
page.addOrder(new OrderItem("balance",true));
// 1.2余额相等的情况下 按照id升序排序
page.addOrder(new OrderItem("id",true));
// 2.分页查询
Page<User> userPage = iUserService.page(page);
// 3.解析
// 总条数
long total = userPage.getTotal();
// 总页数
long pages = userPage.getPages();
// 总数据
List<User> users = userPage.getRecords();
System.out.println("查询起始页为:" + pageNo);
System.out.println("查询的页数为:" + pageSize);
System.out.println("查询的总条数为:" + total);
System.out.println("查询的总页数为:" + pages);
for (User user : users) {
System.out.println(user);
}
}

如果查询出的结果中文显示为乱码,则按照下面的方法进行解决:

在SpringBoot整合Mybatis进行mapper测试查询时,发现返回的中文结果一直是乱码,无论修改yml配置文件还是数据库参数都无法解决,最后发现原因是项目中的SDK以及项目语言级别不对,应该设计JDK1.8,项目语言级别应为8.

测试成功

1.1.3 总结

总结MybatisPlus使用步骤:

  1. 创建MybatisPlusConfog配置类,在配置类中声明MybatisPlusInterceptor拦截器方法
  2. 创建分页插件并添加分页插件
  3. 使用Page.of(pageNo,pageSize)方法传入页码和大小,返回Page<>对象并指定泛型,可以使用page.addOrder指定字段升序降序,true为升序
  4. 使用userService.page(page)的分页方法
  5. 使用page.get__()方法获取数据

1.2 通用分页实体

上述分页只是一个简单的测试,但在实际开发中不会有那么简单的案例

简单分页查询案例:

需求:遵循下面的接口规范,编写一个UserController接口,实现User的分页查询

返回结果

由于分页需求不止查询用户需要,别的业务可能也需要,于是将分页功能单独封装为一个类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@Data
public class PageQuery {
/**
* 页码
*/
private Integer pageNo;
/**
* 页大小
*/
private Integer pageSize;
/**
* 排序字段
*/
private String sortBy;
/**
* 升序降序 false降序 true升序
*/
private boolean isAsc;
}

然后在需要分页功能的类上继承这个方法即可

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
@Data
public class UserQuery extends PageQuery{

/**
* 姓名
*/
private String name;

/**
* 状态
*/
private Integer status;

/**
* 最低余额
*/
private Integer minBalance;

/**
* 最高余额
*/
private Integer maxBalance;
}

统一返回结果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@Data
public class PageDTO<T> {
/**
* 总条数
*/
private Integer total;
/**
* 总页数
*/
private Integer pages;
/**
* 返回数据集合
*/
private List<T> list;
}

1.2.1 编码实现分页查询

  1. 创建业务层接口
1
PageDTO<UserVO> queryUsersPage(UserQuery userQuery);

其中的UserQuery为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
@Data
public class UserQuery extends PageQuery{

/**
* 姓名
*/
private String name;

/**
* 状态
*/
private Integer status;

/**
* 最低余额
*/
private Integer minBalance;

/**
* 最高余额
*/
private Integer maxBalance;
}
  1. 实现业务层接口
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
/**
* 分页查询
* @param userQuery
* @return
*/
@Override
public PageDTO<UserVO> queryUsersPage(UserQuery userQuery) {
// 先获取前端传来的姓名和账号状态
String name = userQuery.getName();
Integer status = userQuery.getStatus();
// 构建分页条件 传入前端传来的页码和分页大小
Page<User> page = Page.of(userQuery.getPageNo(), userQuery.getPageSize());
// 设置排序条件
// 设置条件
// 使用工具类
if (StrUtil.isBlank(userQuery.getSortBy())){
// 排序条件为空,则按照更新时间排序
page.addOrder(new OrderItem("updateTime",false));
} else {
// 排序条件不为空,则按照指定字段排序
page.addOrder(new OrderItem(userQuery.getSortBy(),userQuery.isAsc()));
}
// 分页查询
// 使用MP的Lambda查询
Page<User> userPage = lambdaQuery().like(name != null, User::getUsername, name)
.eq(User::getStatus, status)
.between(userQuery.getMinBalance() != null && userQuery.getMaxBalance() != null
,User::getBalance, userQuery.getMinBalance(), userQuery.getMaxBalance())
.page(page);
// 封装VO结果
PageDTO<UserVO> dto = new PageDTO<>();
dto.setTotal(userPage.getTotal());
dto.setPages(userPage.getPages());
// 获取数据
List<User> users = userPage.getRecords();
// 将users -> userVo
if (CollUtil.isEmpty(users)){
// 如果没查到
dto.setList(Collections.emptyList());
return dto;
}
// 拷贝UserVo
// 使用工具类
List<UserVO> userVOS = BeanUtil.copyToList(users, UserVO.class);
dto.setList(userVOS);
// 返回结果
return dto;
}

其中需要说明的是PageQuery封装了所有需求常见的分页条件,例如pageNo,pageSize,sortBy,isAsc等,在其他查询例如UserQuery中可以继承PageQuery.

PageDTO封装了返回前端的数据,例如pages(总页数),totals总条数以及List<?>返回泛型类型数据集合.

1.3 插件功能-通用分页实体与MP转换

我们自己封装了一部分的分页工具,但是在某些程度上来讲还是比较麻烦的。例如当我们拿到前端传来的UserQuery后还是需要我们自己去构建分页条件然后封装为Page对象,封装的过程比较麻烦,并且代码上与业务没有关系,所以逻辑都是通用的。于是我们可以封装工具类解决这个问题。另一个麻烦的地方是对查询条件的解析然后封装为DTO并判断是否为空,这里与业务逻辑没有关系,这里也需要做封装.

需求

  • 在PageQuery中定义方法,将前端传来的PageQuery对象转换为MybatisPlus中的Page对象
  • 在PageDTO中定义方法,将MybatisPlus中的page结果转换为PageDTO结果.

在实体类中定义方法是为了使逻辑更加清晰

对PageQuery进行封装

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
@Data
public class PageQuery {
/**
* 页码
*/
private Integer pageNo = 1;
/**
* 页大小
*/
private Integer pageSize = 5;
/**
* 排序字段
*/
private String sortBy;
/**
* 升序降序 false降序 true升序
*/
private boolean isAsc = true;

/**
*
* @param orderItem 可变参数排序条件
* @param <T>
* @return
*/
public <T> Page<T> toMpPage(OrderItem ... orderItem){
// 构建分页条件
Page<T> page = Page.of(pageNo, pageSize);
// 设置排序条件
// 设置条件
if (StrUtil.isBlank(getSortBy())){
// 排序条件为空,则按照更新时间排序
page.addOrder(orderItem);
} else if (orderItem != null){
// 排序条件不为空,则按照指定字段排序
page.addOrder(new OrderItem(getSortBy(),isAsc()));
}
return page;
}

/**
* 按照更新时间降序
* @param <T>
* @return
*/
public <T> Page<T> toMpPageByUpdateTime(){
return toMpPage(new OrderItem("update_time",false));
}

/**
* 按照创建时间降序
* @param <T>
* @return
*/
public <T> Page<T> toMpPageByCreateTime(){
return toMpPage(new OrderItem("create_time",false));
}

/**
* 按照自定义字段进行升序或降序
* @param defaultSortBy 自定义方法
* @param isAsc 升序降序 true 升序 false:降序
* @param <T>
* @return
*/
public <T> Page<T> toMpPageByCustom(String defaultSortBy,boolean isAsc){
return toMpPage(new OrderItem(defaultSortBy,isAsc));
}

}

对封装Vo进行封装代码进行封装

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/**
* userPage转换为PageDTO
* @return
*/
public static <PO,VO> PageDTO<VO> of(Page<PO> userPage,Class<VO> voClass){
// 封装VO结果
PageDTO<VO> dto = new PageDTO<>();
dto.setTotal(userPage.getTotal());
dto.setPages(userPage.getPages());
// 获取数据
List<PO> users = userPage.getRecords();
// 将users -> userVo
if (CollUtil.isEmpty(users)){
// 如果没查到
dto.setList(Collections.emptyList());
return dto;
}
// 拷贝UserVo
List<VO> userVOS = BeanUtil.copyToList(users, voClass);
dto.setList(userVOS);
return dto;
}

最后改善业务层代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/**
* 分页查询
* @param userQuery
* @return
*/
@Override
public PageDTO<UserVO> queryUsersPage(UserQuery userQuery) {

String name = userQuery.getName();
Integer status = userQuery.getStatus();
Page<User> page = userQuery.toMpPageByUpdateTime();
// 分页查询
Page<User> userPage = lambdaQuery().like(name != null, User::getUsername, name)
.eq(User::getStatus, status)
.between(userQuery.getMinBalance() != null && userQuery.getMaxBalance() != null
,User::getBalance, userQuery.getMinBalance(), userQuery.getMaxBalance())
.page(page);
// 封装VO结果返回
return PageDTO.of(userPage,UserVO.class);
}

MybatisPlus学习结束

  • Copyright: Copyright is owned by the author. For commercial reprints, please contact the author for authorization. For non-commercial reprints, please indicate the source.
  • Copyrights ©本博客所有文章除特别声明外,著作权归作者所有。转载请注明出处! yang
  • Visitors: | Views:

请我喝杯咖啡吧~

支付宝
微信