计算机系统应用教程网站

网站首页 > 技术文章 正文

网易工程师推荐的开源神器,一键解决Mybatis分页问题

btikc 2024-10-16 08:21:48 技术文章 15 ℃ 0 评论

背景

有次在同事群里分享了mybatis分页拦截器的使用,有大佬回复介绍了一个开源的PageHelper工具,就去了解学习了一下!没想到很好用。


完整个人面经、笔记梳理和Java架构资料分享(200+页PDF),私信我就可以发给你哈~

简单介绍

首先甩出一个GitHub链接:https://github.com/pagehelper/Mybatis-PageHelper

简单地看了一下源码,其实实际的原理是一样的,自定义了一个分页的拦截器,不过PageHelper拦截的方法是Executor.class中的query方法。

观察源码会发现,PageHelper在完成了select count(1)即计数的功能之后,对于原sql的分页查询,全部在Interceptor中完成了,而不是在select count(1)之后,修改原sql,继续由invocation.proceed()来执行:

// PageInterceptor第113行,查询数量
count = executeAutoCount(executor, countMs, parameter, boundSql, rowBounds, resultHandler);

// PageInterceptor第135行
//执行分页
resultList = executor.query(ms, parameter, RowBounds.DEFAULT, resultHandler, pageKey, pageBoundSql);

// 对查询出来的结果进行处理,转换为自定义的Page对象
return dialect.afterPage(resultList, parameter, rowBounds);

这样做的好处就是可以在sql查询完成之后,继续对返回的List进行处理,例如PageHelper在afterPage方法中做的就是讲返回的List对象中的数据取出,放到Page对象中(Page是继承自List的类,其中增加了pageNum、pageSize、total之类的属性)


示例

首先还是要给sqlSessionFactoryBean注册plugin,不过这一次不能直接在SQLSessionFactoryBean中写入了,因为PageInterceptor需要通过setProperties(Properties properties)方法初始化dialect,如果直接在application-database中通过标签向Spring注册bean,那么这个方法就不会被调用,导致后续的NullPoint异常。

正确的方式是,通过mybatis的config.xml注册plugin:

// 错误方式
	<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="configLocation" value="classpath:mybatis/config.xml"/>
        <property name="mapperLocations" value="classpath:mybatis/mapper/*.xml"/>
        <property name="dataSource" ref="dataSource"/>
        <property name="plugins">
            <array>
                <bean class="com.github.pagehelper.PageInterceptor"/>
            </array>
        </property>
    </bean>
    
// 正确方式
在SQLSessionFactoryBean中引入的config.xml中加入:
	<plugins>
        <plugin interceptor="com.github.pagehelper.PageInterceptor"/>
    </plugins>

接下来,只要在需要使用分页的地方先写一次分页参数:

PageHelper.startPage(1, 5);

然后继续执行dao方法,就可以完成分页:

List<String> testList = sampleDao.listTitle(4281);

此处虽然我是使用List来接受的结果,实际上这是一个Page对象,若想要获得total、pageNum、pageSize等信息,可以直接用Page来接受结果,或者用PageInfo对象来转换结果:

Page<String> testPage = sampleDao.listTitle(4281);

或者:

    List<String> testList = sampleDao.listTitle(4281);
PageInfo<String> pageInfo = new PageInfo<>(testList);


结论

总体而言,PageHelper确实比自己造一个轮子要方便实用的多。

再写两个遇到的坑...

  • 引入PageHelper的时候要注意版本,貌似5.0.0之前的版本,拦截器的类是PageHelper,进入5.0.0之后变为了PageInterceptor
  • 5.0.0之前,注册plugin时要指定dialect,即加入一个参数;现在是不要指定dialect,会默认指定一个通用的,如果自己写很容易写错,例如我测试时写了一个MySqlDialect,结果这个东西并不是这么用的


来源:网易工程师-邱稳斌


有任何问题欢迎留言交流~


整理总结不易,如果觉得这篇文章有意思的话,欢迎转发、收藏,给我一些鼓励~

有想看的内容或者建议,敬请留言!

最近利用空余时间整理了一些精选Java架构学习视频和大厂项目底层知识点,需要的同学欢迎私信我发给你~一起学习进步!有任何问题也欢迎交流~

Java日记本,每日存档超实用的技术干货学习笔记,每天陪你前进一点点~

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表