方式一:使用limit
默认 mysql提供
SELECT * from tb_item LIMIT 0,10
方式二:PageHelper
分页插件动态添加LIMIT 0,10
在执行器执行MapperStatement 前进行拦截。
插件PageHelper支Oracle,Mysql,MariaDB,SQLite,Hsqldb,
PostgreSQL六种数据库分页
开发流程:
第一步:导入插件依赖
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>5.1.2</version>
</dependency>
第二步:配置插件
com.github.pagehelper.PageInterceptor(5.0之后版本使用 )
方案一:在Mybatis的核心配置文件中配置[不推荐]
核心配置文件中配置分页插件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!-- 配置分页插件 -->
<plugins>
<plugin interceptor="com.github.pagehelper.PageInterceptor"></plugin>
</plugins>
</configuration>
需要通过spring的配置文件,加载核心配置文件中的插件
方案二:在Spring的配置文件中配置(推荐)
不再需要mybatis的核心配置文件,使用spring的配置文件替代所有
需配置方言属性:helperDialect
下面是Mybatis核心配置文件中的方式
Spring整合配置文件中代码:
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<property name="mapperLocations" value="classpath:com/qf/mapper/*Mapper.xml"></property>
<property name="plugins">
<array>
<bean class="com.github.pagehelper.PageInterceptor">
<property name="properties">
<props>
<prop key="helperDialect">mysql</prop>
</props>
</property>
</bean>
</array>
</property>
</bean>
第三步:使用插件
在具体执行查询之前进行拦截,简单的就是给需要查询的内容,动态加上limit 以及后面的参数。我们开发的时候不需要手动编写带limit的分页语句。
总页数:来源总记录数. count(*) 使用插件后不需要再编写。
插件用法:
执行动态SQL语句前:加PageHelper.startPage(page,rows);//这里的第一个参数传的是第几页,不是起始位置。
page参数从1开始,不是从0开始。第二页:page输入的是2,不是起始位置。
获取分页结果,执行查询后,使用PageInfo对象封装返回的list,获取分页结果、总记录数getTotal() 。
@Override
public List<ComputerDTO> findByPage(int page, int rows) {
//加入分页
PageHelper.startPage(page,rows);// 对查询的内容进行拦截,动态加入limit及查询的具体参数
//查询所有
TbComputerExample example = new TbComputerExample();
//拦截后查询的内容,不再是所有。
List<TbComputer> tbComputers = tbComputerMapper.selectByExample(example);
//得到总记录数
PageInfo pageInfo = new PageInfo(tbComputers);
long total = pageInfo.getTotal();
System.out.println(total);
List<ComputerDTO> list =new ArrayList<ComputerDTO>();
for (TbComputer tbComputer : tbComputers) {
ComputerDTO dto = new ComputerDTO();
BeanUtils.copyProperties(tbComputer,dto);
dto.setComGendate(ComDate.dateToStr(tbComputer.getComGendate()));
list.add(dto);
}
return list;
}
如何返回总记录数或者总页数给表现层,表现层给页面?
原始方式:
改进后:还可以通过输入参数(对象),返回需要的内容。
或者可以通过返回Map<String,Object>的方法存储集合和分页信息。
表现层:
@RequestMapping("/listCom.do")
public ModelAndView listCom(HttpServletRequest request){
ModelAndView modelAndView = new ModelAndView();
String page = request.getParameter("page");//
int currentPage = 1;
if(StringUtils.isEmpty(page)){//不传page参数,默认从第一页
currentPage =1;
}else {
currentPage = Integer.parseInt(page);
}
PageDTO pageDTO = new PageDTO();
pageDTO.setPage(currentPage);
pageDTO.setSize(5);
List<ComputerDTO> all = computerService.findByPage(pageDTO);
//表现层没有设置总页数,但是服务层有设置总页数,这里可否得到总页数呢?
int maxPage = pageDTO.getMaxPage();
if(currentPage<1){
currentPage=1;
}else if(currentPage>maxPage){
currentPage=maxPage;
}
modelAndView.addObject("comList",all);//传值
modelAndView.addObject("currentPage",currentPage);
modelAndView.addObject("maxPage",maxPage);
modelAndView.setViewName("comlist");//逻辑视图
return modelAndView;
}
分页插件处理了第0页,返回就是第一页的信息;没有处理最后一页+1页,返回空记录。
未来可以把前面查询返回的最大页数存储到分布式缓存中,后面点击下一页的时候先从缓存中取得最大页判断当前页是否大于最大页数。如果大于,就用最大页查询返回最后一页就可以了。
页面:
这里需要注意的部分:
原因:这是pageHelper里面自带的一个功能,叫做reasonable分页参数合理化,3.3.0以上版本可用,默认是false。 启用合理化时,如果pageNum<1会查询第一页,如果pageNum>pages会查询最后一页; 禁用合理化时,如果pageNum<1或pageNum>pages会返回空数据。
解决:一般项目里面加入<property name="reasonable" value="false" />
,spring Boot项目里面:pagehelper.reasonable=false
这里我们可以修改一下配置文件: 当我们点击最后一页的时候 再次点击下一页的时候,会发现,此时不会不限空数据 ,仅仅会出现最后一次的数据。