<select id="selectByPageInfo" resultMap="BaseResult"> select * from tb_user limit #{pageNo}, #{pageSize} </select>
public List<User> findByPageInfo(PageInfo info) { return userMapper.selectByPageInfo(info); }
3,优点
灵活性高,可优化空间大
mysql分页语句优化
4,缺点
实现复杂。
Mybatis提供RowBounds类来实现逻辑分页。RowBounds中有2个字段offset和limit。这种方式获取所有的ResultSet,从ResultSet中的offset位置开始获取limit个记录。但这并不意味着JDBC驱动器会将所有的ResultSet存放在内存,实际上只加载小部分数据到内存,如果需要,再加载部分数据到内存。
<select id="selectPage" resultType="com.example.demo.mapper.one.User"> select * from user </select>
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了。
@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,默认的是RoutingStatementHandler StatementHandler 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:已触发分页拦截器"); //获取进行数据库操作时管理参数的Handler ParameterHandler 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信息了 } }
@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; } }
/** * Interceptor 实现分页,必须以ByInterceptor结构,自定义的Interceptor才能 * 识别出来,并且必须传入PageInfo * @param pageInfo 自定义的分页 * @return */ List<User> 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<User> 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是一个第三方实现的分页拦截器插件,使用起来灵活且方便。
<dependency> <groupId>com.github.pagehelper</groupId> <artifactId>pagehelper</artifactId> <version>最新版本</version> </dependency>
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() { @Override public 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() { @Override public void doSelect() { userMapper.selectGroupBy(); } }); //对应的lambda用法 pageInfo = PageHelper.startPage(1, 10).doSelectPageInfo(() -> userMapper.selectGroupBy()); //count查询,返回一个查询语句的count数 long total = PageHelper.count(new ISelect() { @Override public 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
来源:https://haitao.blog.csdn.net/article/details/120195945?spm=1001.2101.3001.6650.2&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7Edefault-2-120195945-blog-109134466.pc_relevant_multi_platform_whitelistv1&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7Edefault-2-120195945-blog-109134466.pc_relevant_multi_platform_whitelistv1&utm_relevant_index=5