解决Mybatis-Plus操作分页后数据失效问题

业务场景

我们知道在使用PageHelper分页插件时,会对执行PageHelper.startPage(pageNum, pageSize);方法后的第一条查询语句进行分页操作。在开发中总会遇到这样的业务情景,在进行分页查询后,需要对获得的列表数据包装成另一种类型,此时需要对新类型的列表进行分页,然而由于PageInfo<T>因为泛型的原因,导致处理后的列表不能加入到该类中。

如,我在数据库分页后查询到的类为PageInfo<User>,此时改类中的list属性为User,在当前的业务场景下,我需要将User类型替换为UserVo类型。

当我们对list属性进行操作时,会同时导致PageInfo类中的其他属性发生改变,如total等。

解决方法

//从数据库获得的Users分页列表
//当我们打印users时,会发现打印出来的数据除了列表数据还有分页属性
List<User> users = this.list();
//操作users获得的需要的列表
List<UserVo> userVos = this.list2(users);
//创建User的info类,此时page中的属性已生成
PageInfo<User> userPage = new PageInfo<>(users);
//创建UserVo的info类
PageInfo<UserVo> userVoPage= new PageInfo<>(userVos );
//将userPage中除看list外的其他属性复制到userVoPage中
PageInfoUtil pageInfoUtil = new PageInfoUtil();
pageInfo = pageInfoUtil.getPageVo(userPage ,userVoPage);
pageInfoUtil
public class PageInfoUtil {
 public PageInfo getPageVo(PageInfo pageInfoPo,PageInfo pageInfoVo){
  pageInfoVo.setTotal(pageInfoPo.getTotal());
  pageInfoVo.setEndRow(pageInfoPo.getEndRow());
  pageInfoVo.setHasNextPage(pageInfoPo.isHasNextPage());
  pageInfoVo.setHasPreviousPage(pageInfoPo.isHasPreviousPage());
  pageInfoVo.setIsFirstPage(pageInfoPo.isIsFirstPage());
  pageInfoVo.setIsLastPage(pageInfoPo.isIsLastPage());
  pageInfoVo.setNavigateFirstPage(pageInfoPo.getNavigateFirstPage());
  pageInfoVo.setNavigateLastPage(pageInfoPo.getNavigateLastPage());
  pageInfoVo.setNavigatePages(pageInfoPo.getNavigatePages());
  pageInfoVo.setNavigatepageNums(pageInfoPo.getNavigatepageNums());
  pageInfoVo.setNextPage(pageInfoPo.getNextPage());
  pageInfoVo.setPageNum(pageInfoPo.getPageNum());
  pageInfoVo.setPages(pageInfoPo.getPages());
  pageInfoVo.setPageSize(pageInfoPo.getPageSize());
  pageInfoVo.setPrePage(pageInfoPo.getPrePage());
  pageInfoVo.setSize(pageInfoPo.getSize());
  pageInfoVo.setStartRow(pageInfoPo.getStartRow());
  pageInfoVo.setFirstPage(pageInfoPo.getFirstPage());
  pageInfoVo.setLastPage(pageInfoPo.getLastPage());
  return pageInfoVo;
 }
}

End

想使用秀一点的方法,结果能力有限,没有成功,只能使用这种笨方法,如果有更好的方法,欢迎各位指导。

补充知识:mybatis-plus分页无效, total=0问题(springmvc)

前言

项目中(springmvc)分页采用mybatis-plus, 头一回用, 就遇到了如题问题

pom.xml

<dependency>
 <groupId>com.baomidou</groupId>
 <artifactId>mybatis-plus</artifactId>
 <version>3.2.0</version>
</dependency>

mapper继承了BaseMapper

@Repository
public interface UserMapper extends BaseMapper<UserPo>{
  // 这里代码没用, 查询采用的BaseMapper中的 IPage<T> selectPage(IPage<T> page, @Param("ew") Wrapper<T> queryWrapper);
}

service层

 @Override
 public SysUserVo list(UserQo qo) {
  QueryWrapper<UserPo> queryWrapper = new QueryWrapper<>();
  queryWrapper.like("name", qo.getKeyword())
    .or().
    like("code", qo.getKeyword());
  Page<UserPo> page = new Page<>(qo.getPageNo(), qo.getPageSize());
  IPage<UserPo> userPoIPage = userMapper.selectPage(page, queryWrapper);
  List<UserPo> records = userPoIPage.getRecords();
  long total = userPoIPage.getTotal();// 总记录数
  long pages = userPoIPage.getPages();// 查询结果数
  long pageNo = userPoIPage.getCurrent();// 当前页
  long pageSize = userPoIPage.getSize();// 每页条数
  List<UserVo> userVos = Lists.newArrayList();
  for (UserPo userPo : records) {
   Integer userId = userPo.getId();
   List<RolePo> roles = userMapper.selectRoles(userId);
   UserVo userVo = UserVo.builder().code(userPo.getCode())
     .name(userPo.getName())
     .rolePo(roles)
     .status(userPo.getStatus())
     .build();
   userVos.add(userVo);
  }
  SysUserVo sysUserVo = SysUserVo.builder()
    .list(userVos)
    .total(total)
    .build();
  return sysUserVo;
 }

结果分页并没有生效, 于是添加拦截器

package com.cebbank.api.config;

import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import com.baomidou.mybatisplus.extension.plugins.pagination.optimize.JsqlParserCountOptimize;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.annotation.EnableTransactionManagement;

@Configuration
@EnableTransactionManagement
@MapperScan("com.cebbank.api.mapper")
public class MybatisPlusConfig {
 @Bean
 public PaginationInterceptor paginationInterceptor() {
  PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
  // 设置请求的页面大于最大页后操作, true调回到首页,false 继续请求 默认false
  paginationInterceptor.setOverflow(true);
  // 设置最大单页限制数量,默认 500 条,-1 不受限制
  paginationInterceptor.setLimit(100);
  // 开启 count 的 join 优化,只针对部分 left join
  paginationInterceptor.setCountSqlParser(new JsqlParserCountOptimize(true));
  paginationInterceptor.setDialectType("mysql");
  return paginationInterceptor;
 }
}

还是没生效

最后找到解决方案, 在数据源配置中显式添加分页插件

 @Bean
 public SqlSessionFactory sqlSessionFactory() throws Exception {
  MybatisSqlSessionFactoryBean sqlSessionFactoryBean = new MybatisSqlSessionFactoryBean();
  sqlSessionFactoryBean.setDataSource(dataSource());
  MybatisConfiguration configuration = new MybatisConfiguration();
  configuration.setMapUnderscoreToCamelCase(true);
  configuration.setDefaultEnumTypeHandler(EnumOrdinalTypeHandler.class);
  sqlSessionFactoryBean.setConfiguration(configuration);
//  sqlSessionFactoryBean.setMapperLocations(resolveMapperLocations());
  sqlSessionFactoryBean.setPlugins(new Interceptor[]{new PaginationInterceptor()});

  return sqlSessionFactoryBean.getObject();
 }

完整配置

package com.cebbank.api.config;

import com.alibaba.druid.pool.DruidDataSource;
import com.baomidou.mybatisplus.core.MybatisConfiguration;
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.type.EnumOrdinalTypeHandler;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;

import javax.sql.DataSource;

/**
 * @author linyong
 * @date 2020/7/30 16:38
 * @description 数据源配置
 **/
@Configuration
@EnableAspectJAutoProxy
@MapperScan("com.cebbank.api.mapper")
public class DBConfig {

 @Value("${spring.datasource.url}")
 private String url;

 @Value("${spring.datasource.driver-class-name}")
 private String driverClassName;

 @Value("${spring.datasource.username}")
 private String username;

 @Value("${spring.datasource.password}")
 private String password;

 @Value("${spring.datasource.initialSize:5}")
 private Integer initialSize;

 @Value("${spring.datasource.maxActive:50}")
 private Integer maxActive;

 @Value("${spring.datasource.maxWait:60000}")
 private Integer maxWait;

 @Value("${spring.datasource.minIdle:5}")
 private Integer minIdle;

 @Value("${spring.datasource.testWhileIdle:true}")
 private Boolean testWhileIdle;

 @Value("${spring.datasource.testOnBorrow:true}")
 private Boolean testOnBorrow;

 @Value("${spring.datasource.testOnReturn:true}")
 private Boolean testOnReturn;

 @Value("${spring.datasource.validationQuery:select 1}")
 private String validationQuery;

// @Value("${mybatis.mapper-locations}")
// private String mapperLocations;

 @Bean
 public DataSource dataSource(){
  DruidDataSource druidDataSource = new DruidDataSource();
  druidDataSource.setUrl(url);
  druidDataSource.setDriverClassName(driverClassName);
  druidDataSource.setUsername(username);
  druidDataSource.setPassword(password);
  druidDataSource.setInitialSize(initialSize);
  druidDataSource.setMaxActive(maxActive);
  druidDataSource.setMaxWait(maxWait);
  druidDataSource.setMinIdle(minIdle);
  druidDataSource.setTestWhileIdle(testWhileIdle);
  druidDataSource.setTestOnBorrow(testOnBorrow);
  druidDataSource.setTestOnReturn(testOnReturn);
  druidDataSource.setValidationQuery(validationQuery);
  return druidDataSource;
 }

// private Resource[] resolveMapperLocations() {
//  ResourcePatternResolver resourceResolver = new PathMatchingResourcePatternResolver();
//  String[] arr = mapperLocations.split(",");
//  List<String> locations = Arrays.asList(arr);
//  List<Resource> resources = new ArrayList();
//  if (locations != null) {
//   for (String mapperLocation : locations) {
//    try {
//     Resource[] mappers = resourceResolver.getResources(mapperLocation);
//     resources.addAll(Arrays.asList(mappers));
//    } catch (IOException e) {
//     // ignore
//    }
//   }
//  }
//  return resources.toArray(new Resource[resources.size()]);
// }

 @Bean
 public SqlSessionFactory sqlSessionFactory() throws Exception {
  MybatisSqlSessionFactoryBean sqlSessionFactoryBean = new MybatisSqlSessionFactoryBean();
  sqlSessionFactoryBean.setDataSource(dataSource());
  MybatisConfiguration configuration = new MybatisConfiguration();
  configuration.setMapUnderscoreToCamelCase(true);
  configuration.setDefaultEnumTypeHandler(EnumOrdinalTypeHandler.class);
  sqlSessionFactoryBean.setConfiguration(configuration);
//  sqlSessionFactoryBean.setMapperLocations(resolveMapperLocations());
  sqlSessionFactoryBean.setPlugins(new Interceptor[]{new PaginationInterceptor()});

  return sqlSessionFactoryBean.getObject();
 }

 @Bean
 public DataSourceTransactionManager transactionManager(){
  DataSourceTransactionManager transactionManager = new DataSourceTransactionManager();
  transactionManager.setDataSource(dataSource());
  return transactionManager;
 }

}

问题解决!

以上这篇解决Mybatis-Plus操作分页后数据失效问题就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • mybatis-plus分页查询的实现示例

    按照官方文档进行的配置:快速开始|mybatis-plus 引入依赖: <!-- 引入mybatisPlus --> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.2.0</version> </dependency> <!--

  • 解决mybatis plus 分页查询有条数,total和pages都是零的问题

    一. 问题还原 1. Controller代码部分 Page<FixedAssetsEntity> pageForPlus = getPage(); Page<FixedAssetsEntity> fixedAssetsEntityPage = fixedAssetsService.selectPage(pageForPlus); 2.spring-mybatis.xml中的sqlSessionFactory配置 <bean id="sqlSessionFactor

  • MyBatis-Plus 分页查询以及自定义sql分页的实现

    一.引言 分页查询每个人程序猿几乎都使用过,但是有部分同学不懂什么是物理分页和逻辑分页. 物理分页:相当于执行了limit分页语句,返回部分数据.物理分页只返回部分数据占用内存小,能够获取数据库最新的状态,实施性比较强,一般适用于数据量比较大,数据更新比较频繁的场景. 逻辑分页:一次性把全部的数据取出来,通过程序进行筛选数据.如果数据量大的情况下会消耗大量的内存,由于逻辑分页只需要读取数据库一次,不能获取数据库最新状态,实施性比较差,适用于数据量小,数据稳定的场合. 那么MP中的物理分页怎么实现

  • mybatis-plus分页传入参数后sql where条件没有limit分页信息操作

    折腾了差不多两个小时,各种方法尝试,后来想想应该是where过滤后的数据量没有达到默认一页规定的数量所以干脆where就不显示limit信息了,试了一下还真是...这作者还真是把程序做的足够智能,可是这个智能也让我白白花掉了两个小时...还是自己太笨了-- 但是奇怪的是,如果我不设置QueryWrapper参数,where后面的分页限制又是可以出来的.百思不得其解作者的想法... 具体看代码: @Override public PageUtils queryPage(Map<String, Ob

  • 解决Mybatis-Plus操作分页后数据失效问题

    业务场景 我们知道在使用PageHelper分页插件时,会对执行PageHelper.startPage(pageNum, pageSize);方法后的第一条查询语句进行分页操作.在开发中总会遇到这样的业务情景,在进行分页查询后,需要对获得的列表数据包装成另一种类型,此时需要对新类型的列表进行分页,然而由于PageInfo<T>因为泛型的原因,导致处理后的列表不能加入到该类中. 如,我在数据库分页后查询到的类为PageInfo<User>,此时改类中的list属性为User,在当前

  • 使用sessionStorage解决vuex在页面刷新后数据被清除的问题

    1.原因 2.解决方法 localStorage没有时间期限,除非将它移除,sessionStorage即会话,当浏览器关闭时会话结束,有时间期限,具有自行百度 我这里使用sessionStorage,这里需要注意的是vuex中的变量是响应式的,而sessionStorage不是,当你改变vuex中的状态,组件会检测到改变,而sessionStorage就不会了,页面要重新刷新才可以看到改变,所以应让vuex中的状态从sessionStorage中得到,这样组件就可以响应式的变化 3.具体实现

  • vue 解决addRoutes动态添加路由后刷新失效问题

    前言 某些场景下我们需要利用addRoutes动态添加路由,但是刷新后就会失效,前段时间项目里刚好遇到了这个应用场景,所以就花时间研究了一下,做下分享跟记录,说的不对的地方,请大家指正. 应用场景:用户a登录进系统,页面上有个按钮,点击之后会动态添加路由并且跳转,跳转过去之后,用户刷新后也会停留在当前页面. 不点这个按钮,浏览器输入地址,用户会跳到404页面 github:https://github.com/Mrblackant/keepRouter/tree/master 思路 1.用户点击

  • 关于Mybatis使用collection分页问题

    目录 原因 方案 方案一 方案二 扩展 1.集合的嵌套 Select 查询 2.集合的嵌套结果映射 参考: 项目中mybatis分页的场景是非常高频的,当使用ResultMap并配置collection做分页的时候,我们可能会遇到获取当前页的数据少于每页大小的数据问题.使用PagerHelper插件同样会遇到该问题. 原因 引起该问题的原因是当我们使用的是ResultMap集合的嵌套结果映射来处理通过join查询的结果集,映射成Java实体类型的时候,会导致主数据被映射折叠后少于从数据库获取的数

  • 解决mybatis分页插件PageHelper导致自定义拦截器失效

    目录 问题背景 mybatis拦截器使用 使用方法: 注解参数介绍: setProperties方法 bug内容: 自定义拦截器部分代码 PageInterceptor源码: 解决方法: 解决方案一 调整执行顺序 解决方案二 修改拦截器注解定义 问题背景 在最近的项目开发中遇到一个需求 需要对mysql做一些慢查询.大结果集等异常指标进行收集监控,从运维角度并没有对mysql进行统一的指标搜集,所以需要通过代码层面对指标进行收集,我采用的方法是通过mybatis的Interceptor拦截器进行

  • 解决Mybatis的@Param()注解导致分页失效的问题

    @Param注解导致分页失效-分页拦截器 问题描述 在使用mybatis分页时,使用@Param注解传入了两个对象,分页失效,查询出的总是全部的数据. 出现问题时,分页策略为:分页拦截器实现的分页 [错误写法] service写法: public Page<Entity> getByNidAndEntity(Page<Entity> page,String nid,Entity entity){ entity.setPage(page); page.setList(dao.getB

  • 解决J2EE-session在浏览器关闭后失效问题

    前几天在做一个签到系统时,遇到了喜闻乐见的session问题,项目为Spring+SpringMVC+Mybatis框架,maven管理目录的javaweb端系统,对于session的一些问题,作出以下分析,在这里,着重讨论session生命周期的问题,至于其他定义,不做解释: 首先,说明一下session的生命周期: 存储:Session存储在服务器端,一般为了防止在服务器的内存中(为了高速存取),Sessinon在用户访问第一次访问服务器时创建,需要注意只有访问JSP.Servlet等程序时

  • 解决reload(sys)后print失效的问题

    python版本: python2.7.6 #查看python默认编码格式 >>> import sys >>> print sys.getdefaultencoding() #python 2.x 默认编码是ascii格式; python 3.x 默认编码是utf-8格式 ascii #设置python默认的编码格式 >>> import sys >>> print sys.setdefaultencoding('utf-8') 操

  • 解决mybatis plus 一对多分页查询问题

    最近用mybatis plus做项目,单表的增删改查都正常,做到 1对多表的分页时,用resultMap返回的时候发现返回的记录和总数对不上 返回的记录是 一 表的,二返回的总数是 多 表 查了一下,这个或者是PLUS的bug 大概的解决办法如下图:用collection,传参用column,我这里用了一个小技巧, 把外面传入的参数,作为主表的column传入到从表. 这里没找到其他方法,有其他方法可以评论告诉我 补充知识:解决Mybatis-plus利用collection查询一对多分页数据的

随机推荐