MyBatis

您所在的位置:网站首页 mybatisplus分页拦截器启动 MyBatis

MyBatis

2024-07-08 14:35| 来源: 网络整理| 查看: 265

创作来源:本来项目是用mybatis的mybatisX里面默认添加的分页插件来实现项目分页查询功能,其实也挺简便的,但是希望mybatis全部升级为plus,也就把这个也改了,其实个人感觉mybatis本身的一些mapper方法也挺好用的,有一些也很方便,但是大体上还是plus优先。

一、配置分页插件

注意:在未引入分页插件的情况下,MybatisPlus是不支持分页功能的,IService和BaseMapper中的分页方法都无法正常起效。 所以,我们必须配置分页插件。

在项目中新建一个配置类MyBatisConfiguration,放在项目的config包下面,当然根据个人喜好。如下图所示:

 在配置类添加MyBatisConfiguration配置信息,代码如下:

参考官方文档:分页插件 | MyBatis-Plus

@Configuration public class MyBatisConfiguration { //mybatis-plus分页插件 //详细文档:https://baomidou.com/guide/page.html#使用-starter @Bean public MybatisPlusInterceptor mybatisPlusInterceptor(){ MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); // 1.创建分页插件 PaginationInnerInterceptor paginationInnerInterceptor = new PaginationInnerInterceptor(DbType.MYSQL); paginationInnerInterceptor.setMaxLimit(1000L); // 2.添加分页插件 interceptor.addInnerInterceptor(paginationInnerInterceptor); return interceptor; } }

在配置好后接下来就是通用分页实体等等的编写及接口的开发。

二、分页实体的编写 1、先定义一个统一接收前端的通用分页实体PageQuery

给PageQuery类定义一些通用属性并且提供一些反复用得到的方法

默认通过create_time,update_time来排序,当然这些要和数据库字段统一

@Data @Builder @AllArgsConstructor @NoArgsConstructor @ApiModel(description = "分页查询实体") public class PageQuery { @ApiModelProperty("页码") private Long pageNo; @ApiModelProperty("每页显示记录数") private Long pageSize; @ApiModelProperty("排序字段") private String sortBy; @ApiModelProperty("是否升序") private Boolean isAsc; public Page toMpPage(OrderItem ... items){ // 1.分页条件 Page page = Page.of(pageNo, pageSize); // 2.排序条件 if(StrUtil.isNotBlank(sortBy)){ // 不为空 OrderItem orderItem=new OrderItem(); //排序方式 orderItem.setAsc(isAsc); //排序字段 orderItem.setColumn(sortBy); page.addOrder(orderItem); }else if(items != null){ // 为空,默认排序 page.addOrder(items); } return page; } public Page toMpPage(String defaultSortBy, boolean isAsc){ OrderItem orderItem=new OrderItem(); //排序方式 orderItem.setAsc(isAsc); //排序字段 orderItem.setColumn(defaultSortBy); return this.toMpPage(orderItem); } public Page toMpPageDefaultSortByCreateTimeDesc() { return toMpPage("create_time", false); } public Page toMpPageDefaultSortByUpdateTimeDesc() { return toMpPage("update_time", false); } } 2、再编写一些具体前端需要传的分页需要的类来继承PageQuery @Data public class EmployeePageQueryDTO extends PageQuery implements Serializable { // //页码 // private Long pageNo; // //每页显示记录数 // private Long pageSize; //员工姓名 private String name; } 3、定义通用返回的VO类--》PageResult,返回给前端

因为分页查询所需的就3个属性,总记录数,总页数,分页查询得到的数据,所以这个是统一的VO类

/** * 封装分页查询结果 */ @Data @AllArgsConstructor @NoArgsConstructor public class PageResult implements Serializable { private Long total; //总记录数 private Long pages; //总页数 private List records; //当前页数据集合 } 三、开发接口 1、controller

controller中的方法基本没有什么影响,该怎么写就怎么写,这里提供两种通过接口传参数的案例

/** * 员工分页查询 * @param employeePageQueryDTO * @return */ @GetMapping("/page") @ApiOperation("员工分页查询") public Resultpage(EmployeePageQueryDTO employeePageQueryDTO){ log.info("员工分页查询,参数为:{}",employeePageQueryDTO); PageResult pageResult= employeeService.pageQuery(employeePageQueryDTO); return Result.success(pageResult); } /** * 历史订单查询 * * @param page * @param pageSize * @param status 订单状态 1待付款 2待接单 3已接单 4已完成 5已取消 * @return */ @GetMapping("/historyOrders") @ApiOperation("历史订单查询") public Result page(Long page, Long pageSize, Integer status) { PageResult pageResult = orderService.pageQueryUser(page, pageSize, status); return Result.success(pageResult); } 2、serviceI public interface EmployeeService extends IService { /** * 分页查询 * @param employeePageQueryDTO * @return */ PageResult pageQuery(EmployeePageQueryDTO employeePageQueryDTO); } public interface OrderService extends IService { /** * 历史订单分页查询 * @param pageNum * @param pageSize * @param status 订单状态 1待付款 2待接单 3已接单 4已完成 5已取消 * @return */ PageResult pageQueryUser(Long pageNum, Long pageSize, Integer status); } 3、serviceImpl

两种不同的接口传到service参数在Impl有两种不同写法,实际上就是一种基本的,但是我之前在PageQuery分页实体类里面写了对应的便捷方法

@Service public class EmployeeServiceImpl extends ServiceImpl implements EmployeeService { @Override public PageResult pageQuery(EmployeePageQueryDTO employeePageQueryDTO) { //使用mybatisPlus自带的分页插件 //mybatisX里面默认添加的分页插件和该插件只能存在一个,如果想转换必须导包 //mybatisX里面的属性为int //mybatisPlus里面的属性为long // 1.构建分页条件 Page page = employeePageQueryDTO.toMpPageDefaultSortByCreateTimeDesc(); // 2.分页查询 Page p=lambdaQuery() .like(employeePageQueryDTO.getName() != null,Employee::getName, employeePageQueryDTO.getName()) .page(page); // 3.调用插件获得数据 //获得总的记录数 long total = p.getTotal(); //获得总的页数 long pages = p.getPages(); //获得当前页数据集合 List records = p.getRecords(); // 4.返回封装好的分页结果 return new PageResult(total,pages,records); } }

 在上面这个Impl里面我使用了之前已经PageQuery分页实体类封装的方法来创建分页条件

@Slf4j @Service public class OrderServiceImpl extends ServiceImpl implements OrderService { /** * 历史订单查询 * * @param pageNum * @param pageSize * @param status 订单状态 1待付款 2待接单 3已接单 4已完成 5已取消 * @return */ @Override public PageResult pageQueryUser(Long pageNum, Long pageSize, Integer status) { // 1.构建条件 // 1.1.分页条件 Page page = Page.of(pageNum, pageSize); OrdersPageQueryDTO ordersPageQueryDTO=new OrdersPageQueryDTO(); ordersPageQueryDTO.setUserId(BaseContext.getCurrentId()); ordersPageQueryDTO.setStatus(status); // 分页条件查询 Pagep=lambdaQuery() .like(ordersPageQueryDTO.getNumber()!=null,Orders::getNumber,ordersPageQueryDTO.getNumber()) .like(ordersPageQueryDTO.getPhone()!=null,Orders::getPhone,ordersPageQueryDTO.getPhone()) .eq(ordersPageQueryDTO.getUserId()!=null,Orders::getUserId,ordersPageQueryDTO.getUserId()) .eq(ordersPageQueryDTO.getStatus()!=null,Orders::getStatus,ordersPageQueryDTO.getStatus()) .ge(ordersPageQueryDTO.getBeginTime()!=null,Orders::getOrderTime,ordersPageQueryDTO.getBeginTime()) .le(ordersPageQueryDTO.getEndTime()!=null,Orders::getOrderTime,ordersPageQueryDTO.getEndTime()) //按订单时间排序 .orderByDesc(Orders::getOrderTime) .page(page); List ordersList = p.getRecords(); List list = new ArrayList(); // 查询出订单明细,并封装入OrderVO进行响应 if (ordersList!=null&& ordersList.size()>0){ for (Orders orders : ordersList) { Long orderId = orders.getId();//订单id // 查询订单明细 // List orderDetails = orderDetailMapper.getByOrderId(orderId); QueryWrapper OrderDetailWrapper = new QueryWrapper(); OrderDetailWrapper.lambda().eq(OrderDetail::getOrderId, orderId); List orderDetails =orderDetailMapper.selectList(OrderDetailWrapper); OrderVO orderVO = new OrderVO(); BeanUtils.copyProperties(orders, orderVO); orderVO.setOrderDetailList(orderDetails); list.add(orderVO); } } return new PageResult(p.getTotal(),p.getPages(),list); } }

这个Impl就是按照普通的构建分页条件,传入所需要的参数,在设置排序方式在分页条件查询里面orderByDesc(Orders::getOrderTime),但是两种Impl的对分页查询的操作实际原理是一样的。都是经过类似下面的操作:

// 1.1.分页条件 Page page = Page.of(pageNum, pageSize); // 分页条件查询 Pagep=lambdaQuery() .like(ordersPageQueryDTO.getNumber()!=null,Orders::getNumber,ordersPageQueryDTO.getNumber()) .like(ordersPageQueryDTO.getPhone()!=null,Orders::getPhone,ordersPageQueryDTO.getPhone()) .eq(ordersPageQueryDTO.getUserId()!=null,Orders::getUserId,ordersPageQueryDTO.getUserId()) .eq(ordersPageQueryDTO.getStatus()!=null,Orders::getStatus,ordersPageQueryDTO.getStatus()) .ge(ordersPageQueryDTO.getBeginTime()!=null,Orders::getOrderTime,ordersPageQueryDTO.getBeginTime()) .le(ordersPageQueryDTO.getEndTime()!=null,Orders::getOrderTime,ordersPageQueryDTO.getEndTime()) //按订单时间排序 .orderByDesc(Orders::getOrderTime) .page(page); List ordersList = p.getRecords(); return new PageResult(p.getTotal(),p.getPages(),list); // 1.构建分页条件 Page page = employeePageQueryDTO.toMpPageDefaultSortByCreateTimeDesc(); // 2.分页查询 Page p=lambdaQuery() .like(employeePageQueryDTO.getName() != null,Employee::getName, employeePageQueryDTO.getName()) .page(page); // 3.调用插件获得数据 //获得总的记录数 long total = p.getTotal(); //获得总的页数 long pages = p.getPages(); //获得当前页数据集合 List records = p.getRecords(); // 4.返回封装好的分页结果 return new PageResult(total,pages,records);

记得那个分页条件查询那边

.like(employeePageQueryDTO.getName() != null,Employee::getName, employeePageQueryDTO.getName())

记得在第一个参数加上

employeePageQueryDTO.getName() != null

不加的话如果你是字符串,到时候sql查询的时候拼接就会出现 %null% 的情况导致分页查询无结果

注意 : 在写serviceImpl的时候,我本来想留着一部分的分页查询,但是同一个impl里面似乎不允许导入两种分页查询插件,导入一个另外一个就报错,只能使用一种,而且mybatisX的分页插件里面有属性是Integer,而mybatisplus里面的分页插件是Long ,如果你这个项目想两个都用,在封装分页实体类就特别麻烦,要弄两种。不建议。

上面的serviceImpl还省略了mapper的注入,实际操作 还是要注入的

 4、mapper

mapper里面之前mybatis写的分页查询功能,当然是删掉了或注释掉了

@Mapper public interface EmployeeMapper extends BaseMapper { // Page pageQueuery(EmployeePageQueryDTO employeePageQueryDTO); } 四、Page

该类继承了 IPage 类,实现了 简单分页模型 如果你要实现自己的分页模型可以继承 Page 类或者实现 IPage 类,可参考官方文档:分页插件 | MyBatis-Plus

下面给出这个的一些属性,方便使用方法的时候调用对应需要的方法:

属性名类型默认值描述recordsListemptyList查询数据列表totalLong0查询列表总记录数sizeLong10每页显示条数,默认 10currentLong1当前页ordersListemptyList排序字段信息,允许前端传入的时候,注意 SQL 注入问题,可以使用 SqlInjectionUtils.check(...) 检查文本optimizeCountSqlbooleantrue自动优化 COUNT SQL 如果遇到 jSqlParser 无法解析情况,设置该参数为 falseoptimizeJoinOfCountSqlbooleantrue自动优化 COUNT SQL 是否把 join 查询部分移除searchCountbooleantrue是否进行 count 查询,如果只想查询到列表不要查询总记录数,设置该参数为 falsemaxLimitLong单页分页条数限制countIdStringxml 自定义 count 查询的 statementId 也可以不用指定在分页 statementId 后面加上 _mpCount 例如分页 selectPageById 指定 count 的查询 statementId 设置为 selectPageById_mpCount 即可默认找到该 SQL 执行



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3