1.分页的本质意义:
在前面的开发中我发现pagehelper的分页没有进行处理,网上找了一个操作的方法在我们的代码中进行了一个分页计算的操作,后来想想有点可怕,我们将所有的数据查询出来之后对它进行了计算处理,那么如果数据量非常大的话,系统只能奔溃,二分页的本质在于我们在数据库查询时进行limit的操作来进行分页,所以遵循本质!
附加未实现的代码处理方式(代码中处理方式) //实现分页的主要代码
public ResultVO serviceApplyList(Integer pageNumber, Integer pageSize, String params) {
log.info ("开始获取服务列表");
Map jsonArray = JSON.parseObject (params);
~~//实现分页的主要代码
int pageNumberPara = getPageNumber (pageNumber);
int pageSizePara = pageSize == null || pageSize == 0 ? 9 : pageSize;
PageHelper.startPage (pageNumberPara, pageSizePara);~~
if (params != null && !jsonArray.get ("name").equals ("")) {
String name = (String) jsonArray.get ("name");
//根据系统名称模糊查询系统id
QueryWrapper<SystemEntity> systemQuery = new QueryWrapper<> ();
systemQuery.like ("NAME", name);
List<SystemEntity> systemEntityList = systemMapper.selectList (systemQuery);
//根据系统id查询相关联的服务id
List serId = new ArrayList<> ();
for (SystemEntity systemEntity : systemEntityList) {
QueryWrapper<MappingSystemServeEntity> systemQuerySystemServe = new QueryWrapper<> ();
systemQuerySystemServe.eq ("SYSTEMID", systemEntity.getSystemid ());
List<MappingSystemServeEntity> mappingSystemServeEntities1 = mappingSystemServeMapper.selectList (systemQuerySystemServe);
mappingSystemServeEntities1.forEach (mappingSystemServeEntity -> serId.add (mappingSystemServeEntity.getServiceid ()));
}
if (name.length () > 0 && serId.size () <= 0) {
return ResultUtil.fail ("该系统下无服务,请重新选择");
}
if (serId != null && serId.size () > 0) {
List<ServeVO> serviceApplyList = new ArrayList<> ();
for (Object str : serId) {
List<ServeVO> serveVO = serveMapper.selectServeVO ((String) str);
for (ServeVO serve : serveVO) {
serviceApplyList.add (serve);
}
}
~~//实现分页的主要代码
PageInfo<ServeVO> pageInfo = new PageInfo<> (serviceApplyList);
log.info ("获取服务列表结束");
return ResultUtil.success ("查询成功", PageModel.getPageModel (pageInfo, serviceApplyList));~~
}
} else {
~~//实现分页的主要代码
List<ServeVO> serviceApplyList = serveMapper.selectServeList ();
PageInfo<ServeVO> pageInfo = new PageInfo<> (serviceApplyList);
log.info ("获取服务列表结束");
return ResultUtil.success ("查询成功", PageModel.getPageModel (pageInfo, serviceApplyList));~~
}
return null;
}
getPageModel方法:
public static <T> PageModel<T> getPageModel(PageInfo info, List<T> rows) {
PageModel<T> pageModel = new PageModel<>();
pageModel.setPageSize(info.getPageSize());
//这个是PageInfo对象没有实现时的处理操作,这种是取出所有数据进行计算处理的操作,危险 !!!
List pageLimit = getPageLimit (rows, info.getPageNum () < 1 ? 1 : info.getPageNum (), info.getPageSize ());
pageModel.setRows (info.getList ());
pageModel.setTotal((int) info.getTotal());
pageModel.setTotalPage(info.getPages());
pageModel.setPageNumber(info.getPageNum() < 1 ? 1 : info.getPageNum());
return pageModel;
}
* 根据传入的页数进行分页处理
*/
public static List getPageLimit(List dataList, int pageNum, int pageSize) {
if (CollectionUtils.isEmpty (dataList)) {
return dataList;
}
List resultList = new ArrayList ();
// 所有dataList数据中的第几条
int currIdx = pageNum > 1 ? (pageNum - 1) * pageSize : 0;
for (int i = 0; i < pageSize && i < dataList.size () - currIdx; i++) {
resultList.add (dataList.get (currIdx + i));
}
return resultList;
}
2.分页的场景:
分页的场景使用非常广泛,今天的项目中遇到了这个问题,在我们的使用中用到的无非就是mybatis-plus自带的分页插件,还有就是pagehelper的分页了;在实际开发中,由于业务会变得复杂,所以使用mbatis-plus这种进行单表的分页查询操作,往往无法满足我们的业务,那么我们只能使pagehelper的操作来实现。
以下为mybatis-plus的分页模式:
public PageModel<SystemEntity> selectPmSystem(Integer pageNumberPara, Integer pageSizePara) {
int pageNumber = getPageNumber (pageNumberPara);
int pageSize = pageSizePara == null || pageSizePara == 0 ? 9 : pageSizePara;
//这里也可以使用pagehelper的方式进行分页
//pagehelper的分页方式
// PageHelper.startPage (pageNumber, pageSize);
// List<SystemEntity> systemList = systemMapper.selectPmSystem ();
// PageInfo<SystemEntity> pageInfo = new PageInfo (systemList);
// pageInfo.setPageSize (pageSize);
// pageInfo.setPageNum (pageNumber);
// int pages = systemList.size ()/ pageSize + 1;
// pageInfo.setPages (pages);
// PageModel<SystemEntity> pageModel = PageModel.getPageModel (pageInfo, systemList);
// 改为mybatis-plus进行数据分页
//这里我们只是对单个表进行查询分页,所以我们直接使用mybatis-plus自带的selectPage()方法进行查询分页处理
Page<SystemEntity> page = new Page<> (pageNumber, pageSize);
IPage<SystemEntity> entityIpage = systemMapper.selectPage (page, null);
PageModel<SystemEntity> pageModel = new PageModel<> ();
pageModel.setRows (entityIpage.getRecords ());
pageModel.setPageNumber ((int) (entityIpage.getCurrent ()));
pageModel.setTotal ((int) (entityIpage.getTotal ()));
pageModel.setPageSize ((int) entityIpage.getSize ());
pageModel.setTotalPage ((int) entityIpage.getPages ());
return pageModel;
}
3.解释为什么第一次使用时 PageInfo没有进行内部分页处理的问题:
在我们使用mybatis-plus或者是pagehelper时,我们都需要将配置文件配置好,在我们使用pagehelper时,它所支持的分页插件Interceptor为mybatis的,但我的配置中使用的分页插件是mybatis-plus的,所以致使我们的方法没有生效,下面我贴出没有修改的和修改之后的配置文件信息进行对比
没有修改前,默认用的是mybatis-plus的:
/**
* 配置分页插件
*
*/
@Configuration
public class MybatisPlusConfig {
/**
* 分页插件
* mybatis-plus的
*/
@Bean
public PaginationInterceptor paginationInterceptor() {
return new PaginationInterceptor();
}
@Primary
@Bean(name = "sqlSessionFactory")
//@Autowired PaginationInterceptor paginationInterceptor 只注入了mybatis-plus的插件
public SqlSessionFactory sysSqlSessionFactory(@Autowired @Qualifier("dataSource") DataSource dataSource,@Autowired PaginationInterceptor paginationInterceptor)
throws Exception {
MybatisSqlSessionFactoryBean bean = new MybatisSqlSessionFactoryBean();
// SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(dataSource);
bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath*:mapper/*.xml"));
//只有mybatis-plus的
Interceptor[] plugins = {paginationInterceptor};
bean.setPlugins (plugins);
return bean.getObject();
}
}
两个都有的:
/**
* 配置分页插件
*
*/
@Configuration
public class MybatisPlusConfig {
/**
* 分页插件
*/
//mybatis-plus的
@Bean
public PaginationInterceptor paginationInterceptor() {
return new PaginationInterceptor();
}
//mybatis的拦截配置
@Bean
public PageInterceptor paginationInterceptor2() {
Properties properties = new Properties();
properties.setProperty("helperDialect", "Oracle");
properties.setProperty("offsetAsPageNum", "true");
properties.setProperty("rowBoundsWithCount", "true");
properties.setProperty("reasonable", "true");
properties.setProperty("supportMethodsArguments", "true");
PageInterceptor pageInterceptor = new PageInterceptor();
pageInterceptor.setProperties(properties);
return pageInterceptor;
}
//@Autowired PageInterceptor pageInterceptor, @Autowired PaginationInterceptor paginationInterceptor 将两个的分页插件都注入进来,方便两种分页方式的混合使用
@Primary
@Bean(name = "sqlSessionFactory")
public SqlSessionFactory sysSqlSessionFactory(@Autowired @Qualifier("dataSource") DataSource dataSource,@Autowired PageInterceptor pageInterceptor,
@Autowired PaginationInterceptor paginationInterceptor)
throws Exception {
MybatisSqlSessionFactoryBean bean = new MybatisSqlSessionFactoryBean();
// SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(dataSource);
bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath*:mapper/*.xml"));
//将两个的plugins都放进来
Interceptor[] plugins = {pageInterceptor,paginationInterceptor};
bean.setPlugins (plugins);
return bean.getObject();
}
}
追加:
如果不配置PaginationInterceptor或者PageInterceptor ,MP或pagehelper提供的分页方法是无效的,例如使用mysql,配置了PaginationInterceptor,调用MP提供的分页方法,假设使用selectPage方法,**他会执行两条sql语句,一条查询总记录数的sql,一条查询当前页记录的sql是带limit分页条件的。**如果不配置,调用selectPage只会执行一条查询记录的sql,并且不带limit。