MyBatis本身有分页查询,但是并不是正真的分页查询,它是把数据查出来放在内存里面,你想要什么就给你什么。我们使用MyBatis实现分页查询的时候,是要实现真分页查询,就是要用sql语句来实现分页查询。
有两种翻页方式,一种是逻辑翻页(假分页),一种是物理翻页(真分页)。逻辑翻页的原理是把所有数据查出来,在内存中删选数据。物理翻页是真正的翻页,比如MySQL使用limit语句,Oracle使用ROWNUM语句,SQLServer使用top语句。
逻辑分页
MyBatis里面有一个逻辑分页对象RowBounds,里面主要有两个属性,offset 和limit (从第几条开始,查询多少条)。
我们可以在Mapper接口的方法上加上这个参数,不需要修改xml里面的 SQL语句。
public List selectBlogList(RowBounds rowBounds);
使用:MyBatis-standalone- MyBatisTest-testSelectByRowBounds ()
int start=10; // offset,从第几行开始查询
int pageSize = 5; // limit,查询多少条
RowBounds rb = new RowBounds(start, pageSize);
List list = mapper.selectBlogList(rb);
for(Blog b :list) {
System. out. println(b);
}
它的底层其实是对ResultSet的处理。它会舍弃掉前面offset条数据,然后再取剩下的数据的limit条。
// DefaultResultSetHandler.java
private void handleRowValuesForSimpleResultMap(ResultSetWrapper rsw, ResultMap resuItMap, ResultHandler<? > resuItHandler, RowBounds rowBounds, ResultMapping parentMapping) throws SQLException {
DefaultResultContext resultContext = new DefaultResultContext ();
ResultSet resultSet = rsw. getResultSet ();
this. skipRows(resultSet, rowBounds);
while(this. shouldProcessMoreRows(resultContext, rowBounds)
&& !resultSet. isClosedO && resultSet. next()) {
ResultMap discriminatedResultMap = this. resolveDiscriminatedResultMap(resultSet,
resultMap, (String)null);
Object rowValue = this.getRowValue(rsw, discriminatedResultMap, (String)null); this.storeObject(resultHandler, resultContext, rowValue, parentMapping, resultSet); }
}
很明显,如果数据量大的话,这种翻页方式效率会很低(跟查询到内存中再使用subList(start, end)没什么区别)。所以我们要用到物理分页。
物理分页
物理分页是真正的分页,它是通过数据库支持的语句来分页
第一种简单的办法就是传入参数(或者包装一个page对象),在SQL语句中分页。

第一个问题是我们要在Java代码里面去计算起止序号;第二个问题是:每个需要翻页的Statement都要编写limit语句,会造成Mapper映射器里面很多代码冗余。
那我们就需要一种通用的方式,不需要去修改配置的任何一条SQL语句,只要在我们需要翻页的地方封装一下翻页对象就可以了。
我们最常用的做法就是使用翻页的插件,这个是基于MyBatis的拦截器实现的, 比如 PageHelper。
// pageSize每一页几条
PageHelper.startPage(pn, 10);
List emps = employeeService.getAll(); // navigatePages 导航页码数
Pagelnfo page = new PageInfo(emps, 10);
return Msg.success().add("pagelnfo", page);
PageHelper是通过MyBatis的拦截器实现的,插件的具体原理我们后面再分析。简单地来说,它会根据PageHelper的参数,改写我们的SQL语句。比如MySQL会生成limit语句,Oracle会生成ROWNUM语句,SQLServer会生成top语句。

Was this helpful?

0 / 0

发表回复 0

Your email address will not be published.


© 2024 开发喵