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

如有錯誤,還望指正!
 
        

  

  

 
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM