MyBatis如何使用PageHelper实现分页查询
这篇文章主要介绍了MyBatis如何使用PageHelper实现分页查询,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
目录
使用PageHelper实现分页查询
1、创建数据表
2、创建项目
2.1 创建实体类(Entity层)
2.2 数据库映射层(Mapper层)
3、运行测试
MyBatis PageHelper的使用
1、引入pagehelper的jar包
2、在mybatis的配置文件中配置拦截(也可以在spring配置文件中配置)
3、代码中如何实现
4、注意事项 分页不安全的情况
使用PageHelper实现分页查询
【实例】MyBatis使用PageHelper实现分页查询,并显示分页信息。执行效果如下图:
1、创建数据表
在MySQL数据库中创建用户信息表(tb_user),并添加数据。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | -- 判断数据表是否存在,存在则删除 DROP TABLE IF EXISTS tb_user; -- 创建“用户信息”数据表 CREATE TABLE IF NOT EXISTS tb_user ( user_id INT AUTO_INCREMENT PRIMARY KEY COMMENT '用户编号' , user_name VARCHAR (50) NOT NULL COMMENT '用户姓名' , province VARCHAR (50) NOT NULL COMMENT '省份' , create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '注册时间' ) COMMENT = '用户信息表' ; -- 添加数据 INSERT INTO tb_user(user_name,province) VALUES ( 'pan_junbiao的博客_01' , '广东省' ),( 'pan_junbiao的博客_02' , '黑龙江省' ),( 'pan_junbiao的博客_03' , '山东省' ),( 'pan_junbiao的博客_04' , '安徽省' ),( 'pan_junbiao的博客_05' , '黑龙江省' ), ( 'pan_junbiao的博客_06' , '江苏省' ),( 'pan_junbiao的博客_07' , '黑龙江省' ),( 'pan_junbiao的博客_08' , '广东省' ),( 'pan_junbiao的博客_09' , '陕西省' ),( 'pan_junbiao的博客_10' , '广东省' ), ( 'pan_junbiao的博客_11' , '广东省' ),( 'pan_junbiao的博客_12' , '江苏省' ),( 'pan_junbiao的博客_13' , '陕西省' ),( 'pan_junbiao的博客_14' , '安徽省' ),( 'pan_junbiao的博客_15' , '山东省' ), ( 'pan_junbiao的博客_16' , '陕西省' ),( 'pan_junbiao的博客_17' , '安徽省' ),( 'pan_junbiao的博客_18' , '江苏省' ),( 'pan_junbiao的博客_19' , '黑龙江省' ),( 'pan_junbiao的博客_20' , '安徽省' ), ( 'pan_junbiao的博客_21' , '江苏省' ),( 'pan_junbiao的博客_22' , '广东省' ),( 'pan_junbiao的博客_23' , '安徽省' ),( 'pan_junbiao的博客_24' , '陕西省' ),( 'pan_junbiao的博客_25' , '广东省' ), ( 'pan_junbiao的博客_26' , '广东省' ),( 'pan_junbiao的博客_27' , '安徽省' ),( 'pan_junbiao的博客_28' , '山东省' ),( 'pan_junbiao的博客_29' , '山东省' ),( 'pan_junbiao的博客_30' , '黑龙江省' ), ( 'pan_junbiao的博客_31' , '广东省' ),( 'pan_junbiao的博客_32' , '江苏省' ),( 'pan_junbiao的博客_33' , '陕西省' ),( 'pan_junbiao的博客_34' , '安徽省' ),( 'pan_junbiao的博客_35' , '山东省' ); |
2、创建项目
(1)创建SpringBoot项目,项目结构如下图:
(2)添加pom.xml配置信息
在pom.xml配置文件中添加PageHelper、 MySQL的JDBC数据库驱动。
1 2 3 4 5 6 7 8 9 10 11 12 13 | <!-- SpringBoot/MyBatis使用PageHelper分页控件 --> < dependency > < groupId >com.github.pagehelper</ groupId > < artifactId >pagehelper-spring-boot-starter</ artifactId > < version >1.2.13</ version > </ dependency > <!-- MySQL的JDBC数据库驱动 --> < dependency > < groupId >mysql</ groupId > < artifactId >mysql-connector-java</ artifactId > < version >8.0.20</ version > </ dependency > |
(3)配置相关信息
将默认的application.properties文件的后缀修改为“.yml”,即配置文件名称为:application.yml,并配置以下信息:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | spring: #DataSource数据源 datasource: url: jdbc:mysql: //localhost:3306/db_admin?useSSL=false& username: root password: 123456 driver- class -name: com.mysql.cj.jdbc.Driver #MyBatis配置 mybatis: type-aliases- package : com.pjb.entity #别名定义 configuration: log-impl: org.apache.ibatis.logging.stdout.StdOutImpl #指定 MyBatis 所用日志的具体实现,未指定时将自动查找 map-underscore-to-camel- case : true #开启自动驼峰命名规则(camel case )映射 lazy-loading-enabled: true #开启延时加载开关 aggressive-lazy-loading: false #将积极加载改为消极加载(即按需加载),默认值就是 false lazy-load-trigger-methods: "" #阻挡不相干的操作触发,实现懒加载 cache-enabled: true #打开全局缓存开关(二级环境),默认值就是 true #MyBatis使用pageHelper分页 pagehelper: helper-dialect: mysql reasonable: true support-methods-arguments: true |
配置说明:
helper-dialect:配置使用哪种数据库语言,不配置的话pageHelper也会自动检测。
reasonable:在启用合理化时,如果 pageNum<1,则会查询第一页;如果 pageNum>pages,则会查询最后一页。
support-methods-arguments:支持通过Mapper接口参数来传递分页参数,默认值false,分页插件会从查询方法的参数值中,自动根据上面 params 配置的字段中取值,查找到合适的值时就会自动分页。
2.1 创建实体类(Entity层)
在com.pjb.entity包中,创建UserInfo类(用户信息实体类)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | package com.pjb.entity; import org.springframework.stereotype.Component; import java.util.Date; /** * 用户信息实体类 * @author pan_junbiao **/ @Component public class UserInfo { private int userId; //用户编号 private String userName; //用户姓名 private String province; //省份 private Date createTime; //注册时间 //省略getter与setter方法... @Override public String toString() { return "编号:" + this .getUserId() + " 姓名:" + this .getUserName() + " 省份:" + this .getProvince(); } } |
在com.pjb.entity包中,创建UserSearchParam类(用户查询条件类)。
1 2 3 4 5 6 7 8 9 10 11 | package com.pjb.entity; /** * 用户查询条件类 * @author pan_junbiao **/ public class UserSearchParam { private String userName; //用户姓名 private String province; //省份 //省略getter与setter方法... } |
2.2 数据库映射层(Mapper层)
在com.pjb.mapper包中,创建UserMapper接口(用户信息Mapper动态代理接口)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | package com.pjb.mapper; import com.pjb.entity.UserInfo; import com.pjb.entity.UserSearchParam; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.SelectProvider; import org.apache.ibatis.jdbc.SQL; import org.springframework.stereotype.Repository; import java.util.List; /** * 用户信息Mapper动态代理接口 * @author pan_junbiao **/ @Mapper @Repository public interface UserMapper { /** * 查询用户列表 */ @SelectProvider (type = UserSqlBuilder. class , method = "searchUserList" ) public List<UserInfo> searchUserList(UserSearchParam param); //建议将SQL Builder以映射器接口内部类的形式进行定义 public class UserSqlBuilder { public String searchUserList(UserSearchParam param) { return new SQL() { { SELECT( "*" ); FROM( "tb_user" ); WHERE( "1 = 1" ); if (param!= null ) { //用户姓名 if (param.getUserName()!= null && param.getUserName().length()> 0 ) { WHERE( "user_name like '%${userName}%'" ); } //省份 if (param.getProvince()!= null && param.getProvince().length()> 0 ) { WHERE( "province = #{province}" ); } } } }.toString(); } } } |
3、运行测试
【运行】查询第2页的用户数据,每页10条数据,并根据创建时间排序。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | @Autowired private UserMapper userMapper; /** * 分页查询用户列表 * @author pan_junbiao */ @Test public void searchUserByParam() { int pageIndex = 2 ; ///获取第2页的数据 int pageSize = 10 ; //每页10条数据 String orderBy = "create_time ASC" ; //排序 //分页信息 PageHelper.startPage(pageIndex, pageSize, orderBy); //查询条件类 UserSearchParam userSearchParam = new UserSearchParam(); //userSearchParam.setUserName("pan_junbiao的博客"); //查询条件1 //userSearchParam.setProvince("广东省"); //查询条件2 //执行分页查询 PageInfo<UserInfo> userInfoPage = new PageInfo<UserInfo>(userMapper.searchUserList(userSearchParam)); //打印用户列表 System.out.println( "\n" ); List<UserInfo> userInfoList = userInfoPage.getList(); userInfoList.stream().forEach(System.out::println); //打印分页信息 System.out.println( "当前页码:第" + userInfoPage.getPageNum() + "页" ); System.out.println( "分页大小:每页" + userInfoPage.getPageSize() + "条" ); System.out.println( "数据总数:共" + userInfoPage.getTotal() + "条" ); System.out.println( "总页数:共" + userInfoPage.getPages() + "页" ); } |
PageInfo类提供的相关属性如下:
执行结果:
MyBatis PageHelper的使用
1、引入pagehelper的jar包
如果是maven项目,pom里添加依赖:
1 2 3 4 5 | < dependency > < groupId >com.github.pagehelper</ groupId > < artifactId >pagehelper</ artifactId > < version >4.1.4</ version > </ dependency > |
2、在mybatis的配置文件中配置拦截(也可以在spring配置文件中配置)
小编在mybatis配置文件SqlMapConfig.xml中配置的
1 2 3 4 5 6 7 8 9 10 11 12 | <? 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 > < plugins > < plugin interceptor = "com.github.pagehelper.PageHelper" > <!--设置数据可类型Oracle,Mysql,MariaDB,SQLite,Hsqldb,PostgreSQL六种数据库--> < property name = "dialect" value = "mysql" /> </ plugin > </ plugins > </ configuration > |
在spring中配置如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | <!--配置SqlSessionFactory对象 --> < bean id = "sqlSessionFactory" class = "org.mybatis.spring.SqlSessionFactoryBean" > < property name = "dataSource" ref = "dataSource" /> < property name = "configLocation" value = "classpath:mybatis-config.xml" /> < property name = "typeAliasesPackage" value = "com.aoChine.model.entity" /> < property name = "mapperLocations" value = "classpath:mapper/*.xml" /> <!-- 配置mybatis分页插件PageHelper --> < property name = "plugins" > < array > < bean class = "com.github.pagehelper.PageInterceptor" > < property name = "properties" > <!-- 什么都不配,使用默认的配置 --> < value ></ value > </ property > </ bean > </ array > </ property > </ bean > |
3、代码中如何实现
Service中一个方法示例:
EasyUIDataGridResult是自己封装的一个pojo,如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | public class EasyUIDataGridResult implements Serializable { private long total; private List rows; public long getTotal() { return total; } public void setTotal( long total) { this .total = total; } public List getRows() { return rows; } public void setRows(List rows) { this .rows = rows; } } |
如果不需要的话直接返回PageInfo就可以
4、注意事项 分页不安全的情况
分页不安全的情况
PageHelper 方法使用了静态的 ThreadLocal 参数,分页参数和线程是绑定的。
只要你可以保证在 PageHelper 方法调用后紧跟 MyBatis 查询方法,这就是安全的。因为 PageHelper 在 finally 代码段中自动清除了 ThreadLocal 存储的对象。
如下代码是不安全的:
1 2 3 4 5 6 7 | PageHelper.startPage( 1 , 10 ); List<Country> list; if (param1 != null ){ list = countryMapper.selectIf(param1); } else { list = new ArrayList<Country>(); } |
这种情况下由于 param1 存在 null 的情况,就会导致 PageHelper 生产了一个分页参数,但是没有被消费,这个参数就会一直保留在这个线程上。当这个线程再次被使用时,就可能导致不该分页的方法去消费这个分页参数,这就产生了莫名其妙的分页。
写成如下便安全了:
1 2 3 4 5 6 7 | List<Country> list; if (param1 != null ){ PageHelper.startPage( 1 , 10 ); list = countryMapper.selectIf(param1); } else { list = new ArrayList<Country>(); } |
另外也可以手动清理ThreadLocal存储的分页参数:
1 | PageHelper.clearPage(); |
以上为个人经验,希望能给大家一个参考
原文链接:https://blog.csdn.net/pan_junbiao/article/details/106789631