LIMIT关键字
-
mapper代码
select * from tb_user limit #{pageNo}, #{pageSize} -
业务层直接调用
public List findByPageInfo(PageInfo info) {
return userMapper.selectByPageInfo(info);
}
3,优点
灵活性高,可优化空间大
mysql分页语句优化
4,缺点
实现复杂。
RowBounds实现分页
Mybatis提供RowBounds类来实现逻辑分页。RowBounds中有2个字段offset和limit。这种方式获取所有的ResultSet,从ResultSet中的offset位置开始获取limit个记录。但这并不意味着JDBC驱动器会将所有的ResultSet存放在内存,实际上只加载小部分数据到内存,如果需要,再加载部分数据到内存。
-
mapper代码
select * from user -
dao代码
List<User> selectPage(RowBounds rowBounds);
-
分页查询
List<User> users = userMapper.selectPage(new RowBounds(5, 10));log.info("users:{}",users);
查询结果:
users:[User(id=6, username=柳云璇, grade=小三(5)班, age=25, phone=17358053274, sex=女), User(id=7, username=酆雨寒, grade=高一(5)班, age=19, phone=15394214112, sex=女), User(id=8, username=郑春阳, grade=小三(7)班, age=24, phone=15004202411, sex=男)]
- 优点
使用起来比直接limit简单。
5,缺点
DB压力比较大,因为将结果暂存在db了。
Interceptor实现
-
自定义Interceptor
@Intercepts({@Signature(type = StatementHandler.class, method = “prepare”, args = {Connection.class, Integer.class})})
public class DefinedPageInterceptor implements Interceptor {@Override public Object intercept(Invocation invocation) throws Throwable {//获取StatementHandler,默认的是RoutingStatementHandlerStatementHandler statementHandler = (StatementHandler) invocation.getTarget();//获取StatementHandler的包装类MetaObject metaObject = SystemMetaObject.forObject(statementHandler);//分隔代理对象while (metaObject.hasGetter("h")) {Object obj = metaObject.getValue("h");metaObject = SystemMetaObject.forObject(obj);}while (metaObject.hasGetter("target")) {Object obj = metaObject.getValue("target");metaObject = SystemMetaObject.forObject(obj);}//获取查看接口映射的相关信息MappedStatement mappedStatement = (MappedStatement) metaObject.getValue("delegate.mappedStatement");String mapId = mappedStatement.getId();//拦截以ByInterceptor结尾的请求,统一实现分页if (mapId.matches(".+ByInterceptor$")) {System.out.println("LOG:已触发分页拦截器");//获取进行数据库操作时管理参数的HandlerParameterHandler parameterHandler = (ParameterHandler) metaObject.getValue("delegate.parameterHandler");// 分页对象需要自己构建,到时候分页方法中要传入 //获取请求时的参数PageInfo info = (PageInfo) parameterHandler.getParameterObject();//获取原始SQL语句String originalSql = (String) metaObject.getValue("delegate.boundSql.sql");//构建分页功能的SQL语句String sql = originalSql.trim() + " limit " + info.getPageNum() + ", " + info.getPageSize();metaObject.setValue("delegate.boundSql.sql", sql);}//调用原对象方法,进入责任链下一级return invocation.proceed(); }@Override public Object plugin(Object target) {//生成Object对象的动态代理对象return Plugin.wrap(target, this); }@Override public void setProperties(Properties properties) {//如果分页每页数量是统一的,可以在这里进行统一配置,也就无需再传入PageInfo信息了 }
}
-
添加到mybatis中
@Bean(“oneSqlSessionFactory”)
public SqlSessionFactory sqlSessionFactory() {
SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
sqlSessionFactoryBean.setDataSource(dataSource);
try {
sqlSessionFactoryBean.setMapperLocations(
// 设置mybatis的xml所在位置
new PathMatchingResourcePatternResolver().getResources(“classpath*:mapping/one/*Mapper.xml”));
//设置自定义的插件
sqlSessionFactoryBean.setPlugins(new DefinedPageInterceptor());
return sqlSessionFactoryBean.getObject();
} catch (Exception e) {
return null;
}
} -
mapper方法
/**
* Interceptor 实现分页,必须以ByInterceptor结构,自定义的Interceptor才能
* 识别出来,并且必须传入PageInfo
* @param pageInfo 自定义的分页
* @return
*/
List selectPageByInterceptor(PageInfo pageInfo);
xml
<select id="selectPageByInterceptor" resultType="com.example.demo.mapper.one.User">select * from user</select>
-
运行
/**
* 自定义PageInterceptor分页
*/
@Test
public void test04() {
PageInfo pageInfo=new PageInfo();
pageInfo.setPageNum(5);
pageInfo.setPageSize(5);
List users = userMapper.selectPageByInterceptor(pageInfo);
log.info(“users:{}”,users);
}
拦截更改后的sql。
-
运行结果
users:[User(id=6, username=柳云璇, grade=小三(5)班, age=25, phone=17358053274, sex=女), User(id=7, username=酆雨寒, grade=高一(5)班, age=19, phone=15394214112, sex=女), User(id=8, username=郑春阳, grade=小三(7)班, age=24, phone=15004202411, sex=男)]
PageHelper
PageHelper是一个第三方实现的分页拦截器插件,使用起来灵活且方便。
-
添加pom
com.github.pagehelper pagehelper 最新版本
2,使用方式
//第一种,RowBounds方式的调用
List<User> list = sqlSession.selectList("x.y.selectIf", null, new RowBounds(0, 10));//第二种,Mapper接口方式的调用,推荐这种使用方式。
PageHelper.startPage(1, 10);
List<User> list = userMapper.selectIf(1);//第三种,Mapper接口方式的调用,推荐这种使用方式。
PageHelper.offsetPage(1, 10);
List<User> list = userMapper.selectIf(1);//第四种,参数方法调用
//存在以下 Mapper 接口方法,你不需要在 xml 处理后两个参数
public interface CountryMapper {List<User> selectByPageNumSize(@Param("user") User user,@Param("pageNum") int pageNum, @Param("pageSize") int pageSize);
}
//配置supportMethodsArguments=true
//在代码中直接调用:
List<User> list = userMapper.selectByPageNumSize(user, 1, 10);//第五种,参数对象
//如果 pageNum 和 pageSize 存在于 User 对象中,只要参数有值,也会被分页
//有如下 User 对象
public class User {//其他fields//下面两个参数名和 params 配置的名字一致private Integer pageNum;private Integer pageSize;
}
//存在以下 Mapper 接口方法,你不需要在 xml 处理后两个参数
public interface CountryMapper {List<User> selectByPageNumSize(User user);
}
//当 user 中的 pageNum!= null && pageSize!= null 时,会自动分页
List<User> list = userMapper.selectByPageNumSize(user);//第六种,ISelect 接口方式
//jdk6,7用法,创建接口
Page<User> page = PageHelper.startPage(1, 10).doSelectPage(new ISelect() {@Overridepublic void doSelect() {userMapper.selectGroupBy();}
});
//jdk8 lambda用法
Page<User> page = PageHelper.startPage(1, 10).doSelectPage(()-> userMapper.selectGroupBy());//也可以直接返回PageInfo,注意doSelectPageInfo方法和doSelectPage
pageInfo = PageHelper.startPage(1, 10).doSelectPageInfo(new ISelect() {@Overridepublic void doSelect() {userMapper.selectGroupBy();}
});
//对应的lambda用法
pageInfo = PageHelper.startPage(1, 10).doSelectPageInfo(() -> userMapper.selectGroupBy());//count查询,返回一个查询语句的count数
long total = PageHelper.count(new ISelect() {@Overridepublic void doSelect() {userMapper.selectLike(user);}
});
//lambda
total = PageHelper.count(()->userMapper.selectLike(user));
- 官网
官网:https://pagehelper.github.io/
使用方式:https://github.com/pagehelper/Mybatis-PageHelper/blob/master/wikis/zh/HowToUse.md
先自我介绍一下,小编13年上师交大毕业,曾经在小公司待过,去过华为OPPO等大厂,18年进入阿里,直到现在。深知大多数初中级java工程师,想要升技能,往往是需要自己摸索成长或是报班学习,但对于培训机构动则近万元的学费,着实压力不小。自己不成体系的自学效率很低又漫长,而且容易碰到天花板技术停止不前。因此我收集了一份《java开发全套学习资料》送给大家,初衷也很简单,就是希望帮助到想自学又不知道该从何学起的朋友,同时减轻大家的负担。添加下方名片,即可获取全套学习资料哦