MyBatis之分页查询

1.逻辑分页

1.逻辑分页主要是指,查询所有的数据,然后我们从内存中,筛选对应的分页信息;
2.MyBatis 里面有一个逻辑分页对象 RowBounds,里面主要有两个属性,offset 和limit(从第几条开始,查询多少条)。
3.可以在 Mapper 接口的方法上加上这个参数,不需要修改 xml 里面的 SQL 语句,如下selectBlogList方法。

如:
BlogMapper.java方法

    public List<Blog> selectBlogList(RowBounds rowBounds);

BlogMapper.xml

 <select id="selectBlogList" resultMap="BaseResultMap" >
  select bid, name, author_id authorId from blog
 </select>

数据库申诉局
在这里插入图片描述

    @Test
    public void testSelectByRowBounds() throws IOException {
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

        SqlSession session = sqlSessionFactory.openSession();
        try {
            BlogMapper mapper = session.getMapper(BlogMapper.class);
            int start = 0; // offset 从第几行开始查询
            int pageSize = 5; // limit 查询多少条
            RowBounds rb = new RowBounds(start, pageSize);
            List<Blog> list = mapper.selectBlogList(rb); // 使用逻辑分页
            for(Blog b :list){
                System.out.println(b);
            }
        } finally {
            session.close();
        }
    }

在这里插入图片描述
原理
DefaultResultSetHandler.handleRowValuesForSimpleResultMap

  private void handleRowValuesForSimpleResultMap(ResultSetWrapper rsw, ResultMap resultMap, ResultHandler<?> resultHandler, RowBounds rowBounds, ResultMapping parentMapping)
      throws SQLException {
    DefaultResultContext<Object> resultContext = new DefaultResultContext<>();
    ResultSet resultSet = rsw.getResultSet();
    skipRows(resultSet, rowBounds);
    while (shouldProcessMoreRows(resultContext, rowBounds) && !resultSet.isClosed() && resultSet.next()) {
      ResultMap discriminatedResultMap = resolveDiscriminatedResultMap(resultSet, resultMap, null);
      Object rowValue = getRowValue(rsw, discriminatedResultMap, null);
      storeObject(resultHandler, resultContext, rowValue, parentMapping, resultSet);
    }
  }
1.它的底层其实是对 ResultSet 的处理。 它会舍弃掉前面 offset 条数据,然后再取剩下的数据的 limit 条;
2.很明显,如果数据量大的话,这种翻页方式效率会很低(跟查询到内存中再使用subList(start,end)没什么区别)。 所以我们要用到物理翻页

2.物理分页

2.1.方式一:手动在SQL中编写

1.传入参数(或者包装一个 page 对象),在 SQL 语句中翻页。
<select id="selectBlogPage" parameterType="map" resultMap="BaseResultMap">
	select * from blog limit #{curIndex} , #{pageSize}
</select>

问题

1.起止序列号需要java程序计算;
2.每个需要翻页的 Statement 都要编写 limit 语句,会造成 Mapper 映射器里面很多代码冗余。

2.2.方式二:插件-pageHelper

2.2.1.pom.xml中引入pageHelper的版本

  <!-- https://mvnrepository.com/artifact/com.github.pagehelper/pagehelper -->
  <dependency>
       <groupId>com.github.pagehelper</groupId>
       <artifactId>pagehelper</artifactId>
       <version>5.1.2</version>
   </dependency>

2.2.2.mybatis-config.xml配置pageHelper的plugin拦截器


<plugins>
   <!-- com.github.pagehelper为PageHelper类所在包名 -->
    <plugin interceptor="com.github.pagehelper.PageInterceptor">
        <!-- 使用下面的方式配置参数,后面会有所有的参数介绍
        详细配置参考
        https://github.com/pagehelper/Mybatis-PageHelper/blob/master/README_zh.md
	 -->
<!--            <property name="param1" value="value1"/>-->
    </plugin>
</plugins>

2.2.3.BlogMapper.xml

    <select id="selectBlogAll" resultMap="BaseResultMap" >
        select bid, name, author_id authorId from blog
    </select>

2.2.4.BlogMapper.java

 public List<Blog> selectBlogAll();

2.2.5.单元测试

    @Test
    public void testSelectByPageHelper() throws IOException {
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

        SqlSession session = sqlSessionFactory.openSession();
        try {
            PageHelper.startPage(1,3);//第1行开始,前三行
            BlogMapper mapper = session.getMapper(BlogMapper.class);
            List<Blog> list = mapper.selectBlogAll();
            for(Blog b :list){
                System.out.println(b);
            }
        } finally {
            session.close();
        }
    }

在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

东山富哥

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值