龙哥网

龙哥网

MyBatis如何使用PageHelper实现分页查询_java(mybatisplus分页和pagehelper)
2022-03-01

目录
  • 使用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),并添加数据。

            -- 判断数据表是否存在,存在则删除
            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数据库驱动。

            <!-- 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的使用

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

            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();
            免责声明
            本站部分资源来源于互联网 如有侵权 请联系站长删除
            龙哥网是优质的互联网科技创业资源_行业项目分享_网络知识引流变现方法的平台为广大网友提供学习互联网相关知识_内容变现的方法。