zoukankan      html  css  js  c++  java
  • SpringBoot+MyBatis多数据源使用分页插件PageHelper

    之前只用过单数据源下的分页插件,而且几乎不用配置。一个静态方法就能搞定。

    PageHelper.startPage(pageNum, pageSize);

    后来使用了多数据源(不同的数据库),PageHelper分页插件需要设定一个默认的数据库,mysql、oracle或者其他。
    但是又不能实时切换,导致请求的第一个类型数据库的请求都可以继续请求,而其他的数据库的请求因为sql语句在不同数据库的count和分页语句不同报错。

    解决思路是
    ①配置先配置多数据源,再配置多个SqlSessionFactory使用不同的数据源,
    SqlSessionFactory同时指定某些dao层接口(或者mapper),此时不同的dao层就可以访问不同数据源
    ②在每个
    SqlSessionFactory中配置一个分页插件

    第一步骤中的多数据源配置很多博文都有记录,在此不再重复写,我配置的时候参考的是这个链接
    http://blog.csdn.net/neosmith/article/details/61202084
    他提供了一个多数据源手动配置,一个自动配置方案。因为我们要在多数据源下另外配置分页插件,所以选用手动配置方案。


    重点讲第二步骤:
    一、多数据源下配置分页插件
      如果你使用的上边的配置方案,那么你现在应该有多个
    SqlSessionFactory的bean。我们重点来看某个SqlSessionFactory bean的配置:
     1 @Configuration
     2 @MapperScan(basePackages = {"com.firstRest.dao.localLeftjointest"}, sqlSessionFactoryRef = "sqlSessionFactory1")
     3 public class MybatisDbAConfig {
     4 
     5     @Autowired
     6     @Qualifier("localLeftjointestDataSource")
     7     private DataSource ds1;
     8 
     9     @Bean
    10     public SqlSessionFactory sqlSessionFactory1() throws Exception {
    11         SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
    12         factoryBean.setDataSource(ds1); // 使用localLeftjointest数据源, 连接leftjointest库
    13 
    14         //分页插件
    15         Interceptor interceptor = new PageInterceptor();
    16         Properties properties = new Properties();
    17         properties.setProperty("helperDialect", "mysql");
    18         properties.setProperty("offsetAsPageNum", "true");
    19         properties.setProperty("rowBoundsWithCount", "true");
    20         properties.setProperty("reasonable", "true");
    21         properties.setProperty("supportMethodsArguments","true");
    22         properties.setProperty("params","pageNum=pageNumKey;pageSize=pageSizeKey;");
    23         interceptor.setProperties(properties);
    24         factoryBean.setPlugins(new Interceptor[] {interceptor});
    25 
    26         return factoryBean.getObject();
    27 
    28     }
    29 
    30     @Bean
    31     public SqlSessionTemplate sqlSessionTemplate1() throws Exception {
    32         SqlSessionTemplate template = new SqlSessionTemplate(sqlSessionFactory1()); // 使用上面配置的Factory
    33         return template;
    34     }
    35 }
    多出来的代码就是我们需要添加的地方,我们来看一下到底干了些什么:
    ①新建了一个
    PageInterceptor,因为Mybatis允许在已经映射语句执行过程中某一点进行拦截调用,而PageHelper就是在这进行分页操作的

    ②新建一个属性,并添加一些属性值,这些属性值里重要的是:
      
      (1)helperDialect 数据库方言:数据库是什么就写什么就行 mysql、sqlserver、oracle、db2 这样的,详情参考 https://github.com/pagehelper/Mybatis-PageHelper/blob/master/wikis/en/HowToUse.md
      (2)supportMethodsArguments 是否支持参数方式进行分页:写true就行了,后边写原因
      (3)params 支持了那些参数:pageNum=pageNumKey;pageSize=pageSizeKey。分别对应了分页页码,分页大小。

      需要注意的是:
        有些博文中写的是在①步骤中新建一个PageHelper对象,设置PageHelper的属性,然后添加到Plugins里面去,现在已经不支持这种写法了!  现在就是要用PageInterceptor!
        (2)(3)中设置的是插件是用方案配置,如果这样设置的话,在dao层(或者mapper中)接口同时出现pageNumKey 和 pageSizeKey 参数,这个方法就会被分页。为什么使用这个方法呢,我们之后讲,先这么写就对了。
    单个SqlSessionFactory配置好了,其他的SqlSessionFactory在配置分页插件的时候只需要把helperDialect 修改成另外一个数据源数据库类型即可。


    二、如何写dao层接口
      上边我们设置了
    supportMethodsArguments 和params,如何使分页插件在我们调用dao层方法的时候生效呢?
      代码如下:

    1 @Repository
    2 public interface JlzxDao {
    3     @Select(value = "Select * from ${table_name} order by id")
    4     @ResultType(HashMap.class)
    5     List<HashMap> getAll(@Param("table_name") String tableName,
    6                @Param("pageNumKey") int pageNum,
    7                          @Param("pageSizeKey") int pageSize);
    8 }
    
    
      重点看标红的参数,我并没有把这两个参数在sql中使用,但把两个参数写了进去。这样同时出现pageNumKey 和 pageSizeKey 参数,这个方法就会被分页。

      这样Dao层咋调用的时候多传两个分页参数过去就可以自动分页了。

    三、为何选用这种参数方式使用分页
      在单数据源的时候,我使用的是静态方法,即本文最开始的那行代码进行标示,使下一个查询语句进行分页。
      但使用这种静态方法时,在service层(或者controller层)判断数据源来自哪里之后使用下边的语句,这是我之前的service层的写法:
     1 @Service("BaseService")
     2 public class BasePagingService implements PagingService{
     3     @Autowired
     4     private JlzxDao jlzxDao;
     5     @Autowired
     6     private LeftjointestDao leftjointestDao;
     7 
     8     @Override
     9     public PageInfo<HashMap> selectByPage(String dbName,String tableName,int currentPage, int pageSize){
    10         if(dbName.equals("leftjointest")){
    11             PageHelper.startPage(currentPage, pageSize);
    12             return new PageInfo<>(leftjointestDao.getAll(tableName));
    13         }
    14         else if(dbName.equals("jlzx")){
    15             PageHelper.startPage(currentPage, pageSize);
    16             return new PageInfo<>(jlzxDao.getAll(tableName));
    17         }
    18         return null;
    19 
    20     }
    21 }

      这样的方法会报错:在系统中发现了多个分页插件,请检查系统配置!

      所以换了参数直接写在dao层方法中的用法。




    我的项目链接如下:
    https://github.com/Jaccccccccccccccccccccccccccccck/firstREST

    如有错误,还望指正!
    
    

      

      

     
     
  • 相关阅读:
    Postman提取接口返回值设置变量
    Python-浅拷贝与深拷贝
    Python列表
    typeorm查询两个没有关联关系的实体
    springboot去掉数据源自动加载
    docker搭建redis集群
    实习工作记录(一)大文件上传vue+WebUploader
    js重点之promise
    css重点
    git简单命令整理
  • 原文地址:https://www.cnblogs.com/Jacck/p/8309421.html
Copyright © 2011-2022 走看看