1、介绍:
pagehelper是一个开源的java分页插件,它提供了方便的分页查询功能,适用于大多数基于java的持久层框架(如mybatis、hibernate等)。
在一个程序中难免会使用到查询操作,在查询操作中如果数据量太大则需要进行分页查询,分页操作的实现方法有很多,比如:在 mybatis 中 xml 文件中通过 limit 关键字进行分页查询,该插件就是为了简化在 xml 中进行分页操作的工具;好比在 mybatis-plus 中也对分页操作进行了封装,通过调用 selectpage() 方法就可以实现分页操作。
在 sql 中使用 limit 进行分页查询
select * from user limit 10, 10
- offset 是相对于首行的偏移量(首行是 0),rows 是返回条数
- mapper 中可以传变量,即在实际使用的时候 offset 与 rows 可以用变量替代
我们当然可以在sql中进行分页,但是为了简化代码。
我们还是会使用一些插件来帮我们更好的进行分页操作。如:在项目中我们执行一个分页查询时,很多时候还需要知道该查询的其他信息,比如:总数、每页数量、当前页数、是否有上一页或者是否有下一页等等,这些信息如果每次都自己写的话就会太繁琐冗余了,而 pagehelper 插件能够帮助我们更加方便地获取这些信息,大大方便了我们的开发效率。
我始终认为官网才是一个技术最权威、最公正的对照。如果你在使用某个相应的技术中出现了错误,那么一定要先去官网上查找原因。现在的web开发使用到的框架大多为spring boot,所以本篇文章只是教会你如何快速的在spring boot项目中使用pagehelper分页插件,并介绍一些一些常用的方法,如果你有其他的疑问,可以在官网中查找。
2、新建spring boot项目,并导入依赖
引入pagehelper的坐标(我引入的使pagehelper整合spring boot的依赖)
<dependency> <groupid>org.mybatis.spring.boot</groupid> <artifactid>mybatis-spring-boot-starter</artifactid> <version>3.0.1</version> </dependency> <dependency> <groupid>com.github.pagehelper</groupid> <artifactid>pagehelper-spring-boot-starter</artifactid> <version>1.4.7</version> </dependency>
在yml配置文件中对pagehelper进行一些配置,能更好的使用这个插件;
# pagehelper 分页插件配置 pagehelper: helper-dialect: mysql reasonable: true support-methods-arguments: true params: count=countsql
helper-dialect:指定数据库,不指定的话会默认自动检测数据库类型
reasonable:是否启动分页合理化。如果启用,当 pagenum < 1 时,会自动查询第一页的数据,当 pagenum > pges 时,自动查询最后一页数据;不启用的,以上两种情况都会返回空数据,如果启用则 pagehelper可以自动拦截请求参数中的 pagenum,pagesize参数,否则需要使用 pagehelper.startpage(pagenum,pagesize) 方法调用。
support-methods-arguments:默认为 false,分页插件会从查询方法的参数值中,自动根据上面 params 配置的字段中取值,查找到合适的值时就会自动分页。
params:用于从对象中根据属性名取值,可以配置 pagenum,pagesize,count,pagesizezero,reasonable,不配置映射的用默认值,默认值为 pagenum=pagenum;pagesize=pagesize;count=countsql;reasonable=reasonable;pagesizezero=pagesizezero
创建一个mapper接口:
public interface usersmapper { //查询所有 list<users> getall(); }
mybatis的配置文件:
<?xml version="1.0" encoding="utf-8" ?> <!doctype configuration public "-//mybatis.org//dtd config 3.0//en" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <settings> <!-- 设置驼峰标识 --> <setting name="mapunderscoretocamelcase" value="true"/> <!-- 打印sql语句 --> <setting name="logimpl" value="stdout_logging"/> </settings> <!-- <plugins>--> <!-- <!– 分页插件 –>--> <!-- <plugin interceptor="com.github.pagehelper.pageinterceptor"/>--> <!-- </plugins>--> <mappers> <package name="com.zq.pagehelpdemo.mapper"/> </mappers> </configuration>
我们已经引入了pagehelper-spring-boot-starter的依赖。所以pagehelper插件在项目启动时会自动注入到容器中。如果你的项目不是spring boot项目或者引入的依赖不是pagehelper整合了spring boot的依赖,那么就需要在mybatis的配置文件中引入pagehelper的插件。
在项目中使用pagehelper实现分页:
@override public list<users> getpage(int page, int size) { //获取第page页,size条内容,默认查询总数count pagehelper.startpage(page,size); //分页时,实际返回的结果list类型是page<e>,如果想取出分页信息,需要强制转换为page<e>, return getall(); }
xml中的sql语句:
<select id="getall" resulttype="com.zq.pagehelpdemo.entity.users"> select * from users </select>
运行结果:
在启动项目时看到这个图标就说明pagehelper注入成功了:
sql语句:
可以看到先执行了一个查询所有记录的语句,然后执行了我们在xml中写的查询语句,在查询语句的最后加上了limit字段。
其实这些sql都不是我们写的,我们只不过是写了一个
pagehelper.startpage(page,size);
这一条语句就会帮助我们自动生成分页语句;
注意pagehelper.startpage方法使用也有限制:
pagehelper.startpage方法重要提示
只有紧跟在pagehelper.startpage方法后的第一个mybatis的查询(select)方法会被分页。(pagehelper 启动了一个新的线程)
还有在使用pagehelper插件时的几个重要提示:
请不要配置多个分页插件
请不要在系统中配置多个分页插件(使用spring时,mybatis-config.xml和spring<bean>配置方式,请选择其中一种,不要同时配置多个分页插件)!
分页插件不支持带有for update语句的分页
对于带有for update的sql,会抛出运行时异常,对于这样的sql建议手动分页,毕竟这样的sql需要重视。
分页插件不支持嵌套结果映射
由于嵌套结果方式会导致结果集被折叠,因此分页查询的结果在折叠后总数会减少,所以无法保证分页结果数量正确。
pagehelper使用时,要注意线程的安全性,避免重复调用分页参数:
pagehelper 方法使用了静态的 threadlocal 参数,分页参数和线程是绑定的。
只要你可以保证在 pagehelper 方法调用后紧跟 mybatis 查询方法,这就是安全的。因为 pagehelper 在 finally 代码段中自动清除了 threadlocal 存储的对象。
如果代码在进入 executor 前发生异常,就会导致线程不可用,这属于人为的 bug(例如接口方法和 xml 中的不匹配,导致找不到 mappedstatement 时), 这种情况由于线程不可用,也不会导致 threadlocal 参数被错误的使用。
下面有一段代码示例:
public list<users> getpages(int page, int size) { // 调用pagehelper的静态方法startpage pagehelper.startpage(page, size); list<users> userslist=new arraylist<>(); if (false) { system.out.println("调用了查询方法"); userslist = usersmapper.getall(); } else { system.out.println("没有调用了查询方法"); } return userslist; }
在这个方法中,我调用了pagehelper.startpage方法,这时就会导致pagehelper生产了一个分页参数,但是没有被消费,这个参数就会一直保留在这个线程上。当这个线程再次被使用时,就可能导致可能不该分页的方法去消费这个分页参数,这就产生了莫名其妙的分页。
所以我们一定要保证pagehelper.startpage方法后面跟了一个查询方法。最好的情况就是将这两条语句就放在一起,前后挨着。
当然,使用 pagehelper.startpage进行分页时基本的用法。如果你不仅仅想要得到分页内容,还要得到一些分页具体的值,如查询的总记录数等等。可以使用pageinfo,在这个对象中pagehelper封装了我们对于分页来说的所有参数,可以满足我们对于分页操作的所有需求。
public class pageinfo<t> extends pageserializable<t> { public static final int default_navigate_pages = 8; // 当前页 private int pagenum; // 每页的数量 private int pagesize; // 当前页的数量 private int size; // 下面两个不常用 // 在页面中“显示 startrow” 到 endrow 共 size条数据 // 当前页面中第一个元素的在数据库中的行号 private long startrow; // 当前页面最后一个元素在数据库中的行号 private long endrow; // 总页数 private int pages; // 前一页 private int prepage; // 下一页 private int nextpage; // 是否为第一页 private boolean isfirstpage; // 是否为最后一页 private boolean islastpage; // 是否有前一页 private boolean haspreviouspage; // 是否有下一页 private boolean hasnextpage; // 导航页码数 private int navigatepages; // 所有导航页号 private int[] navigatepagenums; // 导航条上的第一页 private int navigatefirstpage; // 导航条上的最后一页 private int navigatelastpage; ...... }
在代码中使用pageinfo:
(在创建pageinfo时,指定泛型。并将查询到的结果作为入参传递)
@override public pageinfo<users> getpageinfo(int page, int size) { pagehelper.startpage(page,size); list<users> userslist = getall(); // 将查询到的数据封装到pageinfo中 pageinfo<users> pageinfo=new pageinfo<>(userslist); return pageinfo; }
运行结果为:
可以很清晰的看到输出了pageinfo的所有属性,我们可以根据我们的需求动态的获取用到的参数。
以上就是springboot3整合pagehelper实现分页功能的详细内容,更多关于springboot3 pagehelper分页的资料请关注代码网其它相关文章!
发表评论