暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Spring Boot+Mybatis+Pagehelper分页

风尘博客 2019-11-13
1526

Mybatis
自己没有分页功能,我们要做分页的话, 需要写两条SQL
。本文介绍通过PageHelper
工具来实现分页,非常简单方便。

一、项目准备

1.1 数据库准备

    DROP TABLE IF EXISTS `tb_user`;


    CREATE TABLE `tb_user` (
    `id` BIGINT ( 20 ) AUTO_INCREMENT PRIMARY KEY COMMENT "自增主键",
    `user_name` VARCHAR ( 50 ) NOT NULL COMMENT "用户名",
    `user_age` INT ( 3 ) DEFAULT 0 COMMENT "用户年龄"
    ) ENGINE = INNODB DEFAULT CHARSET = utf8 COMMENT "测试用户表";


    -- 插入测试数据


    INSERT INTO `tb_user` VALUES (1, "张三", 27);
    INSERT INTO `tb_user` VALUES (2, "李四", 30);
    INSERT INTO `tb_user` VALUES (3, "王五", 20);

    1.2 pom.xml

      <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-test</artifactId>
      <scope>test</scope>
      </dependency>
      <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
      </dependency>
      <!--mysql-->
      <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      </dependency>
      <!-- mybatis -->
      <dependency>
      <groupId>org.mybatis.spring.boot</groupId>
      <artifactId>mybatis-spring-boot-starter</artifactId>
      <version>2.1.0</version>
      </dependency>
      <!-- pagehelper 分页插件-->
      <dependency>
      <groupId>com.github.pagehelper</groupId>
      <artifactId>pagehelper-spring-boot-starter</artifactId>
      <version>1.2.12</version>
      </dependency>
      <!-- lombok -->
      <dependency>
      <groupId>org.projectlombok</groupId>
      <artifactId>lombok</artifactId>
      <scope>1.8.4</scope>
      </dependency>

      注意:如果使用Myabtis-plus
      的话,需要排除PageHelper
      的依赖mybatis
      mybatis-spring
      jar
      包以免与mybatis-plus
      的冲突,如下:

        <dependency>
        <groupId>com.github.pagehelper</groupId>
        <artifactId>pagehelper-spring-boot-starter</artifactId>
        <version>1.2.12</version>
        <exclusions>
        <exclusion>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        </exclusion>
        <exclusion>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis-spring</artifactId>
        </exclusion>
        </exclusions>
        </dependency>

        1.3 配置文件

        具体配置介绍看代码注解,更多PageHelper
        配置,详见官网文档[1]

          #端口
          #端口
          server:
          port: 8081


          # 数据库配置
          spring:
          datasource:
          url: jdbc:mysql://47.98.178.84:3306/root
          username: root
          password: password
          driver-class-name: com.mysql.cj.jdbc.Driver
          # mybatis
          mybatis:
          mapper-locations: classpath:mapper/*.xml
          type-aliases-package: cn.van.mybatis.demo.entity
          #pagehelper分页插件配置
          pagehelper:
          # 指定数据库
          helper-dialect: mysql
          # 默认是false。启用合理化时,如果pageNum<1会查询第一页,如果pageNum>pages(最大页数)会查询最后一页。禁用合理化时,如果pageNum<1或pageNum>pages会返回空数据
          reasonable: false
          # 是否支持接口参数来传递分页参数,默认false
          support-methods-arguments: true
          # 为了支持startPage(Object params)方法,增加了该参数来配置参数映射,用于从对象中根据属性名取值, 可以配置 pageNum,pageSize,count,pageSizeZero,reasonable,不配置映射的用默认值, 默认值为pageNum=pageNum;pageSize=pageSize;count=countSql;reasonable=reasonable;pageSizeZero=pageSizeZero
          params: count=countSql
          row-bounds-with-count: true
          # sql log
          logging:
          level:
          cn:
          van:
          mybatis:
          demo:
          mapper: debug

          二、示例代码

          2.1 表对应的实体类

            @Data
            public class UserDO {
            private Long id;
            private String userName;
            private Integer userAge;
            }

            2.2 数据库映射

            UserMapper.java

              public interface UserMapper {


              /**
              * 查询单个用户
              * @param id
              * @return
              */
              UserDO selectById(Long id);


              /**
              * 分页查询用户
              * @return
              */
              List<UserDO> selectPage();
              }

              UserMapper.xml

                <?xml version="1.0" encoding="UTF-8"?>
                <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
                <mapper namespace="cn.van.mybatis.demo.mapper.UserMapper" >
                <resultMap id="BaseResultMap" type="cn.van.mybatis.demo.entity.UserDO" >
                <id column="id" property="id"/>
                <result column="user_name" property="userName" />
                <result column="user_age" property="userAge" />
                </resultMap>


                <sql id="Base_Column_List" >
                id, user_name, user_age
                </sql>


                <select id="selectById" resultMap="BaseResultMap">
                select <include refid="Base_Column_List"/>
                from tb_user
                where id = #{id}
                </select>
                <select id="selectPage" resultMap="BaseResultMap">
                select <include refid="Base_Column_List"/>
                from tb_user
                </select>


                </mapper>

                仔细观察就会发现,这里的分页查询的sql
                跟查询就是查询集合的sql
                ,分页交个插件去完成。

                2.3 分页查询参数

                  @Data
                  public class PageParam {
                  /**
                  * 当前页
                  */
                  private int pageNum;
                  /**
                  * 每页数量
                  */
                  private int pageSize;


                  public PageParam(int pageNum, int pageSize) {
                  this.pageNum = pageNum;
                  this.pageSize = pageSize;
                  }
                  }

                  2.4 分页结果的包装类

                    @Data
                    @SuppressWarnings({"rawtypes", "unchecked"})
                    public class PageData<T> implements Serializable {


                    private static final long serialVersionUID = 1L;
                    /**
                    * 当前页
                    */
                    private int pageNum;
                    /**
                    * 每页的数量
                    */
                    private int pageSize;
                    /**
                    * 总记录数
                    */
                    private long total;
                    /**
                    * 总页数
                    */
                    private int pages;
                    /**
                    * 结果集
                    */
                    private List<T> list;
                    /**
                    * 是否为第一页
                    */
                    private boolean isFirstPage = false;
                    /**
                    * 是否为最后一页
                    */
                    private boolean isLastPage = false;




                    public PageData() {
                    }


                    /**
                    * 包装Page对象
                    *
                    * @param list
                    */
                    public PageData(List<T> list) {
                    if (list instanceof Page) {
                    Page page = (Page) list;
                    this.pageNum = page.getPageNum();
                    this.pageSize = page.getPageSize();


                    this.pages = page.getPages();
                    this.list = page;
                    this.total = page.getTotal();
                    } else if (list instanceof Collection) {
                    this.pageNum = 1;
                    this.pageSize = list.size();


                    this.pages = 1;
                    this.list = list;
                    this.total = list.size();
                    }
                    if (list instanceof Collection) {
                    //判断页面边界
                    judgePageBoundary();
                    }
                    }


                    /**
                    * 判定页面边界
                    */
                    private void judgePageBoundary() {
                    isFirstPage = pageNum == 1;
                    isLastPage = pageNum == pages;
                    }
                    }

                    2.5业务实现

                    UserService.java

                      public interface UserService {


                      /**
                      * 查询单个用户
                      * @param id
                      * @return
                      */
                      UserDO selectById(Long id);


                      /**
                      * 分页查询用户
                      * @param pageParam
                      * @return
                      */
                      PageData selectForPage(PageParam pageParam);
                      }

                      UserServiceImpl.java

                        @Service("userService")
                        public class UserServiceImpl implements UserService {


                        @Resource
                        UserMapper userMapper;


                        public UserDO selectById(Long id) {
                        return userMapper.selectById(id);
                        }


                        public PageData selectForPage(PageParam pageParam) {
                        // 使用PageHelper的api分页(指定页数和每页数量)
                        PageHelper.startPage(pageParam.getPageNum(), pageParam.getPageSize());
                        List<UserDO> list = userMapper.selectPage();
                        // 包装Page对象
                        PageData<UserDO> pageData = new PageData<UserDO>(list);
                        return pageData;
                        }
                        }

                        通过观察可以发现:在查询语句上一行添加以上语句,就可以实现分页了。并不需要在具体的sql
                        语句中写limit
                        语句,非常方便。

                        三、测试

                        3.1 分页测试

                          @SpringBootTest
                          @RunWith(SpringRunner.class)
                          public class MybatisTest {


                          @Resource
                          UserService userService;


                          @Test
                          public void selectById() {
                          UserDO userDO = userService.selectById(1l);
                          System.out.println(userDO);
                          }
                          @Test
                          public void selectForPage() {
                          PageParam pageParam = new PageParam(1, 2);
                          PageData<UserDO> pageData = userService.selectForPage(pageParam);
                          System.out.println(pageData);
                          }
                          }

                          通过测试结果可以发现分页查询成功!

                          3.2 查询两次对比

                            /**
                            * 查询两次的时间对比
                            */
                            @Test
                            public void compare() {
                            PageParam pageParam = new PageParam(1,2);
                            Long start = System.currentTimeMillis();
                            PageData<UserDO> pageData = userService.selectForPage(pageParam);
                            System.out.println(System.currentTimeMillis() - start);
                            start = System.currentTimeMillis();
                            PageData<UserDO> page = userService.selectForPage(pageParam);
                            System.out.println(System.currentTimeMillis() - start);
                            System.out.println(page);
                            }

                            结果:

                            第一次第一次
                            657ms14ms

                            原因是?静待后文解析。

                            四、示例源码

                            github 源码[2]

                            文中参考地址

                            [1]
                             官网文档: https://pagehelper.github.io/docs/howtouse/
                            [2]
                             github 源码: https://github.com/vanDusty/SpringBoot-Home/tree/master/springboot-demo-mybatis/mybatis-demo


                            文章转载自风尘博客,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

                            评论