插件功能
拦截器 | 描述 |
---|---|
TenantLineInnerInterceptor | 多租户插件 |
DynamicTableNameInnerInterceptor | 动态表名插件 |
PaginationINnerIntercepor | 分页插件 |
OptimisticLockerInnerInterceptor | 乐观锁插件 |
IllegalSQLInnerInterceptor | SQL性能规范插件,检测并拦截垃圾SQL |
BlockAttackInnerInterceptor | 防止全表更新和删除的插件 |
分页
创建MyBatis插件配置类
与controller同级下创建config包,其中创建MyBatisConfig类
@Configuration // 标识一个类是 Spring IoC 容器中的 Java 配置类。这意味着这个类可以包含用于定义 Bean 的方法,并且这些 Bean 会被 Spring 容器管理。
public class MyBatisConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
// 1.创建分页插件
PaginationInnerInterceptor paginationInnerInterceptor = new PaginationInnerInterceptor(DbType.MYSQL);
paginationInnerInterceptor.setMaxLimit(1000L); // 设置上限
// 2.添加分页插件
interceptor.addInnerInterceptor(paginationInnerInterceptor);
return interceptor;
}
}
Service层
测试代码
@Test
void testPageQuery() {
int pageNo = 1, pageSize = 2;
// 1.准备分页条件
// 1.1分页条件
Page<User> page = Page.of(pageNo, pageSize);
// 1.2排序条件
page.addOrder(new OrderItem("balance", true));
page.addOrder(new OrderItem("id", true));
// 2.分页查询
Page<User> p = userService.page(page);
// 3.解析
long total = p.getTotal();
System.out.println("total = " + total);
long pages = p.getPages();
System.out.println("pages = " + pages);
List<User> users = p.getRecords();
users.forEach(System.out::println);
}
通用分页实体
创建分页查询类PageQuery
@Data
@ApiModel(description = "分页查询实体")
public class PageQuery {
@ApiModelProperty("页码")
private Integer pageNo;
@ApiModelProperty("页内数据数量")
private Integer pageSize;
@ApiModelProperty("排序字段")
private String sortBy;
@ApiModelProperty("是否升序")
private Boolean isAsc;
}
要分页的查询类继承PageQuery
@EqualsAndHashCode(callSuper = true) // 用于在子类中自动生成 equals() 和 hashCode() 方法,同时也考虑了父类的字段
@Data
@ApiModel(description = "用户查询条件实体")
public class UserQuery extends PageQuery{
………………
}
创建统一的分页结果-DTO类-PageDTO
@Data
@ApiModel(description = "分页结果")
public class PageDTO<T> {
@ApiModelProperty("总条数")
private long total;
@ApiModelProperty("总页数")
private long pages;
@ApiModelProperty("集合")
private List<T> list;
}
转成MybatisPlus中的类
PageQuery中创建通用方法
- OrderItem ... items:可变参数,可以传一个,多个或不传
- OrderItem:MP提供的类,用于指定数据库查询结果的排序方式
// OrderItem ... items可变参数,可以传一个,多个或不传
public <T>Page<T> toMpPage(OrderItem ... items) {
// 1 分页条件
Page<T> page = Page.of(pageNo, pageSize);
// 2 排序条件
if (StrUtil.isNotBlank(sortBy)) {
// 不为空
page.addOrder(new OrderItem(sortBy, isAsc));
} else if (items != null){
// 为空,默认按照更新时间排序
page.addOrder(items);
}
return page;
}
// 提供常用方法
public <T> Page<T> toMpPage(String defaultSortBy, Boolean defaultAsc) {
return toMpPage(new OrderItem(defaultSortBy, defaultAsc));
}
public <T> Page<T> toMpPageDefaultSortByCreateTime() {
// OrderItem,MP提供的类,用于指定数据库查询结果的排序方式
return toMpPage(new OrderItem("create_time", false));
}
public <T> Page<T> toMpPageDefaultSortByUpdateTime() {
return toMpPage(new OrderItem("update_time", true));
}
PageDTO中创建通用方法
<PO, VO>
:创建对应的VO,PO泛型Page<PO> p
,Class<VO> clazz
:传入PO对象及要转换成的class字节码类型VO- clazz:使用用户传入的对应实体类,
dto.setList(BeanUtil.copyToList(records, clazz));
- clazz:使用用户传入的对应实体类,
// 创建对应的VO,PO泛型,传入PO对象及要转换成的class字节码类型VO
public static <PO, VO> PageDTO<VO> of(Page<PO> p, Class<VO> clazz) {
PageDTO<VO> dto = new PageDTO<>();
// 1 总条数
dto.setTotal(p.getTotal());
// 2 总页数
dto.setPages(p.getPages());
// 3 当前页数据
List<PO> records = p.getRecords();
if (CollUtil.isEmpty(records)) {
dto.setList(Collections.emptyList());
return dto;
}
// 4 拷贝user的VO
dto.setList(BeanUtil.copyToList(records, clazz));
return dto;
}
// 自定义VO转换器
// Function<PO, VO> 是 Java 中的函数式接口,它定义了一个函数操作,接受一个类型为 PO 的参数,返回一个类型为 VO 的结果。
public static <PO, VO> PageDTO<VO> of(Page<PO> p, Function<PO, VO> convertor) {
PageDTO<VO> dto = new PageDTO<>();
// 1 总条数
dto.setTotal(p.getTotal());
// 2 总页数
dto.setPages(p.getPages());
// 3 当前页数据
List<PO> records = p.getRecords();
if (CollUtil.isEmpty(records)) {
dto.setList(Collections.emptyList());
return dto;
}
// 4 拷贝user的VO
dto.setList(records.stream().map(convertor).collect(Collectors.toList()));
return dto;
}
在IUserServiceImpl.java中使用
@Override
public PageDTO<UserVO> queryUsersPage(UserQuery query) {
String name = query.getName();
Integer status = query.getStatus();
// 1.构建分页条件
Page<User> page = query.toMpPageDefaultSortByUpdateTime();
// 2.分页查询
Page<User> p = lambdaQuery()
.like(name != null, User::getUsername, name)
.eq(status != null, User::getStatus, status)
.page(page);
// 3.封装VO结果
// return PageDTO.of(p, UserVO.class);
return PageDTO.of(p, user -> {
// 1.拷贝基础属性
UserVO vo = BeanUtil.copyProperties(user, UserVO.class);
// 2.处理特殊逻辑-隐藏用户名后两位
vo.setUsername(vo.getUsername().substring(0, vo.getUsername().length() - 2) + "**");
return vo;
});
}