zoukankan      html  css  js  c++  java
  • SpringBoot使用Mybatis分页插件(10)

    一、配置分页插件

    (1)先导入依赖。

            <!-- 分页工具pageHelper-->
            <dependency>
                <groupId>com.github.pagehelper</groupId>
                <artifactId>pagehelper-spring-boot-starter</artifactId>
                <version>1.2.10</version>
            </dependency>
    

    (2)在yml中加入分页配置。这里指明是mysql数据库。配置部分搭建完毕。

    spring:
      pagehelper:
        #指明数据库
        helperDialect: mysql
        # when pageNum<=0 ,query first page
        # when pageNum > max count , query last page
        reasonable: true
        supportMethodsArguments: true
        params: count=countSql 

    二、编写拦截器

    分页插件提供的主要类叫做: PageRowBounds。

    一般分页传递的参数是 start  、page 、 limit。

    编写如下的拦截器,拦截住前端的分页相关参数。根据这些分页参数,构造出分页插件需要的PageRowBounds对象。 然后再把这个PageRowBounds对象存放到当前线程中,这里使用到了ThreadLocal技术。ThreadLocal技术的原理就是,把要被存放的数据作为"线程局部变量"存放到线程中。以后不管这个线程执行到哪里,都能够取到 "线程局部变量"。最后当请求执行完毕后,再用拦截器的后处理PostHandler,清除掉"线程局部变量"。

    (1)编写分页拦截器。

    package com.hanzhenya.learnspringboot.interceptor;
     
     
    import com.github.pagehelper.PageRowBounds;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.lang.Nullable;
    import org.springframework.stereotype.Component;
    import org.springframework.web.bind.ServletRequestUtils;
    import org.springframework.web.servlet.ModelAndView;
    import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
     
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
     
    @Component
    public class PageHelperInterceptor extends HandlerInterceptorAdapter {
     
        private static final Logger LOGGER = LoggerFactory.getLogger(PageHelperInterceptor.class);
     
        private static final String PAGE = "page";
        private static final String LIMIT = "limit";
        private static final int DEFAULT_PAGE_INDEX = 0;
        private static final int DEFAULT_PAGE_SIZE = 10;
     
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
     
            //原生的int类型可能会有空指针异常,无法将null赋值给基本数据类型
            Integer page = ServletRequestUtils.getIntParameter(request, PAGE);
            Integer limit = ServletRequestUtils.getIntParameter(request, LIMIT);
            if (null == page || page < 1) {
                page = DEFAULT_PAGE_INDEX;
            } else {
                page = page - 1;
            }
            if (null == limit || limit < 0) {
                limit = DEFAULT_PAGE_SIZE;
            }
            int start = page * limit;
     
            LOGGER.info("分页资源预处理");
            LOGGER.info("从第{}条记录开始查询,共查询{}条记录", start + 1, limit);
     
            //generate an page object and put it into threadLocal
            PageRowBounds pageRowBounds = new PageRowBounds(start, limit);
            PageHelperThreadLocal.setPageInfo(pageRowBounds);
            return true;
        }
     
        @Override
        public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {
            //when the business process has been completed,
            //removing page object which is in the threadLocal
            PageHelperThreadLocal.clean();
        }
     
    }
    

    (2)编写ThreadLocal,用于存放线程局部变量

    package com.hanzhenya.learnspringboot.interceptor;
     
     
    import com.github.pagehelper.PageRowBounds;
     
    public final class PageHelperThreadLocal {
     
        private static final ThreadLocal<PageRowBounds> PAGE_INFO = new ThreadLocal<>();
     
        /**
         * 为调用的线程存储 线程局部变量 PageRowBounds(分页信息封装在此对象里)
         */
        public static void setPageInfo(PageRowBounds rowBounds) {
            PAGE_INFO.set(rowBounds);
        }
     
        /**
         * 获取调用此方法的线程的 线程局部变量 PageRowBounds
         */
        public static PageRowBounds getPageInfo() {
            return PAGE_INFO.get();
        }
     
        /**
         * 清除掉当前线程中的线程局部变量
         */
        public static void clean() {
            PAGE_INFO.remove();
        }
    }
    

    (3)将拦截器配置到项目中。

    package com.hanzhenya.learnspringboot.config;
     
    import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
    import com.zhoutianyu.learnspringboot.interceptor.MyInterceptor;
    import com.zhoutianyu.learnspringboot.interceptor.PageHelperInterceptor;
    import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
    import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
     
    import javax.annotation.Resource;
     
    @Configuration
    public class CustomWebConfigure implements WebMvcConfigurer {
     
        @Resource
        private PageHelperInterceptor pageHelperInterceptor;
     
        @Override
        public void addInterceptors(InterceptorRegistry registry) {
            registry.addInterceptor(pageHelperInterceptor).addPathPatterns("/**").excludePathPatterns("/static/**");
        }
    }  

    三、调用分页工具
             编写Controller、Mapper、mapper.xml进行测试。

             重点需要关注的是如何使用分页插件。

             在Dao层查询的方法上,一定要将分页对象PageRowBounds作为方法的参数,才能使用我们的分页插件。

    package com.hanzhenya.learnspringboot.mybatis;
     
    import com.zhoutianyu.learnspringboot.interceptor.PageHelperThreadLocal;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RestController;
     
    import java.util.List;
     
    @RestController
    public class UserController {
     
        private static final Logger LOGGER = LoggerFactory.getLogger(UserController.class);
     
        @Autowired
        private UserMapper mapper;
     
        @GetMapping(value = "mybatis/getUsers")
        public List<User> getUsers() {
            return mapper.getUsers(PageHelperThreadLocal.getPageInfo());
        }
    }
    

     mapper层

    package com.hanzhenya.learnspringboot.mybatis;
     
    import com.github.pagehelper.PageRowBounds;
    import org.apache.ibatis.annotations.Mapper;
     
    import java.util.List;
     
    @Mapper
    public interface UserMapper {
     
        List<User> getUsers(PageRowBounds pageRowBounds);
    }
    

     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="com.hanzhenya.learnspringboot.mybatis.UserMapper">
        <resultMap id="BaseResultMap" type="com.hanzhenya.learnspringboot.mybatis.User">
     
            <id column="id" jdbcType="BIGINT" property="id"/>
            <result column="username" jdbcType="VARCHAR" property="username"/>
            <result column="age" jdbcType="INTEGER" property="age"/>
        </resultMap>
        <sql id="Base_Column_List">
        id, username, age
      </sql>
     
        <select id="getUsers" resultType="com.hanzhenya.learnspringboot.mybatis.User">
            select
            <include refid="Base_Column_List"/>
            from t_user
        </select>
    </mapper>
    

      注意:在实际使用过程中还需要考虑数据库的数据量。如果某张表的数据量很大,动辄三四十万条记录,手动分页还是有必要的。因此,分表在数据库设计过程也是十分重要的。对于分页插件来说,分页插件也不是万能的,它还是把查到的数据存储到内存中,可能会导致内存溢出风险

  • 相关阅读:
    [SAP Rolling Out] Unit TEST/INTEGRATION TEST/UAT TEST/PARREL TESTING
    针式PKM与众不同的地方
    针式PKM拖动收集功能兼容所有的浏览器
    周九常:个人知识管理的三个重点领域
    关闭word文件老是说normal.dot被另外一人使用
    针式PKM初级应用:修改知识点的颜色评介
    寻找识货的人
    针式PKM中级应用如何将知识管理应用到新项目研发中
    针式PKM中级应用在10秒以内找到本月收集的任意文章
    针式PKM中级应用:知识点之间如何链接
  • 原文地址:https://www.cnblogs.com/h-z-y/p/14602244.html
Copyright © 2011-2022 走看看