欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

MyBatis如何使用PageHelper实现分页查询

程序员文章站 2022-03-10 13:25:13
目录使用pagehelper实现分页查询1、创建数据表2、创建项目2.1 创建实体类(entity层)2.2 数据库映射层(mapper层)3、运行测试mybatis pagehelper的使用1、引...

使用pagehelper实现分页查询

【实例】mybatis使用pagehelper实现分页查询,并显示分页信息。执行效果如下图:

MyBatis如何使用PageHelper实现分页查询

1、创建数据表

在mysql数据库中创建用户信息表(tb_user),并添加数据。

-- 判断数据表是否存在,存在则删除
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项目,项目结构如下图:

MyBatis如何使用PageHelper实现分页查询

(2)添加pom.xml配置信息

在pom.xml配置文件中添加pagehelper、 mysql的jdbc数据库驱动。

<!-- 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,并配置以下信息:

spring:
  #datasource数据源
  datasource:
    url: jdbc:mysql://localhost:3306/db_admin?usessl=false&amp
    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类(用户信息实体类)。

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类(用户查询条件类)。

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动态代理接口)。

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条数据,并根据创建时间排序。

@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实现分页查询

执行结果:

MyBatis如何使用PageHelper实现分页查询

mybatis pagehelper的使用

1、引入pagehelper的jar包

如果是maven项目,pom里添加依赖:

<dependency>                           
  <groupid>com.github.pagehelper</groupid>
     <artifactid>pagehelper</artifactid>
     <version>4.1.4</version>
</dependency>

2、在mybatis的配置文件中配置拦截(也可以在spring配置文件中配置)

小编在mybatis配置文件sqlmapconfig.xml中配置的

<?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中配置如下:

<!--配置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中一个方法示例:

MyBatis如何使用PageHelper实现分页查询

easyuidatagridresult是自己封装的一个pojo,如下:

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 存储的对象。

如下代码是不安全的:

pagehelper.startpage(1, 10);
list<country> list;
if(param1 != null){
    list = countrymapper.selectif(param1);
} else {
    list = new arraylist<country>();
}

这种情况下由于 param1 存在 null 的情况,就会导致 pagehelper 生产了一个分页参数,但是没有被消费,这个参数就会一直保留在这个线程上。当这个线程再次被使用时,就可能导致不该分页的方法去消费这个分页参数,这就产生了莫名其妙的分页。

写成如下便安全了:

list<country> list;
if(param1 != null){
    pagehelper.startpage(1, 10);
    list = countrymapper.selectif(param1);
} else {
    list = new arraylist<country>();
}

另外也可以手动清理threadlocal存储的分页参数:

pagehelper.clearpage();

以上为个人经验,希望能给大家一个参考,也希望大家多多支持。