天天看點

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

如有錯誤,還望指正!      
  
      
  

      

轉載于:https://www.cnblogs.com/Jacck/p/8309421.html