使用hibernate 分表作增刪改查

公司項目有一張表的數據量特別大、並且時間越長累積的數據量就越大、java

 

後來DBA決定分表來解決性能問題、web

 

分表是指   一個母體表  一羣子表(結構和字段與母體表徹底同樣) 咱們程序對母表操做其實就是對子表操做、讓其沒法感知有分表這個動做、spring

 

而使用hibernate如何分表呢?sql

 

難道我要寫N個子表類Domain嗎?那累屎我算了、數據庫

 

呵呵、咱們這裏須要hibernate一個攔截器類  org.hibernate.EmptyInterceptorsession

 

這個攔截器作了什麼呢?app

 

hibernate最終會將咱們寫的HQL語句轉換成SQL語句、而當轉換SQL且沒放如數據庫執行的時候、被攔截器就攔住啦、咱們就能夠偷偷的"使壞"啦、性能

 

咱們須要一個本身的類來繼承org.hibernate.EmptyInterceptorthis

 

 

[java] view plain copy.net

  1. package cn.test;  
  2.   
  3. import org.hibernate.EmptyInterceptor;  
  4.   
  5. public class MyInterceptor extends EmptyInterceptor {  
  6.   
  7.     private String targetTableName;// 目標母表名  
  8.     private String tempTableName;// 操做子表名  
  9.   
  10.     public MyInterceptor() {}//爲其在spring好好利用 咱們生成公用無參構造方法  
  11.   
  12.     public java.lang.String onPrepareStatement(java.lang.String sql) {  
  13.         sql = sql.replaceAll(targetTableName, tempTableName);  
  14.         return sql;  
  15.   
  16.     }  
  17.   
  18.     public String getTargetTableName() {  
  19.         return targetTableName;  
  20.     }  
  21.   
  22.     public void setTargetTableName(String targetTableName) {  
  23.         this.targetTableName = targetTableName;  
  24.     }  
  25.   
  26.     public String getTempTableName() {  
  27.         return tempTableName;  
  28.     }  
  29.   
  30.     public void setTempTableName(String tempTableName) {  
  31.         this.tempTableName = tempTableName;  
  32.     }  
  33.   
  34. }  


 

 

hibernate的session會獲取吧?本文就很少作介紹了、

 

好比咱們有個Test 實體類  對應的數據庫的母表名稱 爲 test   而咱們要保存到子表的 test_01要怎麼作呢?

 

 

 

 

[java] view plain copy

  1. public void saveTest(Test test){  
  2.   
  3.     SessionFactory sf = super.getHibernateTemplate().getSessionFactory();//獲取session工廠  
  4.       
  5.     MyInterceptor interceptor = new MyInterceptor();//咱們的攔截器  
  6.       
  7.     interceptor.setTargetTableName("test");//要攔截的目標表名  
  8.       
  9.     interceptor.setTempTableName("test_01");  //要替換的子表名  
  10.       
  11.     Session session = sf.openSession(interceptor);//當前的session使用這個攔截器  
  12.          
  13.        try{  
  14.           
  15.         Transaction tx =  session.beginTransaction();//獲取事務  
  16.         tx.begin();//開啓事務  
  17.         session.saveOrUpdate(test);//保存和更新  
  18.         tx.commit();//提交  
  19.           
  20.        }catch(Exception e){  
  21.         e.printStackTrace();  
  22.        }finally{  
  23.         session.close();  
  24.        }  
  25.       
  26.    }  


 

 

這樣就能把信息存到子表test_01裏啦、並且根本沒人察覺咱們的"使壞"、hibernate還老老實實的本份的作本身的工做呢、

 

CURD動做就這樣被咱們"使壞"着、

 

那咱們老是new 出來 咱們的攔截器 多麼費勁啊、若是我還須要其餘的地方還須要分表的地方、難道我還要再次new出來給多個地方用?

 

這樣咱們就在spring裏多加一個bean 指向咱們的class類

 

 

[plain] view plain copy

  1. <bean id="MyInterceptor" class="cn.test.MyInterceptor"/>  


 

 

而後攔截器從spring拿就能夠了、在setter進去目標表名和替換表名、

 

 咱們項目是web.xml加載了一個實現ApplicationContextAware類的一個類 

 

static 的 ApplicationContext applicationContext  從裏面getBean 就能拿到了

 

這樣就ok啦、

相關文章
相關標籤/搜索