1. 程式人生 > >SpringBoot多數據源使用分頁插件PageHelper

SpringBoot多數據源使用分頁插件PageHelper

col 很多 rep .get acl 之前 ali factory bounds

之前只用過單數據源下的分頁插件,而且幾乎不用配置。一個靜態方法就能搞定。

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

如有錯誤,還望指正!


  

  

 
 

SpringBoot多數據源使用分頁插件PageHelper