公司項目有一張表的數據量特別大、並且時間越長累積的數據量就越大、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
- package cn.test;
-
- import org.hibernate.EmptyInterceptor;
-
- public class MyInterceptor extends EmptyInterceptor {
-
- private String targetTableName;// 目標母表名
- private String tempTableName;// 操做子表名
-
- public MyInterceptor() {}//爲其在spring好好利用 咱們生成公用無參構造方法
-
- public java.lang.String onPrepareStatement(java.lang.String sql) {
- sql = sql.replaceAll(targetTableName, tempTableName);
- return sql;
-
- }
-
- public String getTargetTableName() {
- return targetTableName;
- }
-
- public void setTargetTableName(String targetTableName) {
- this.targetTableName = targetTableName;
- }
-
- public String getTempTableName() {
- return tempTableName;
- }
-
- public void setTempTableName(String tempTableName) {
- this.tempTableName = tempTableName;
- }
-
- }
hibernate的session會獲取吧?本文就很少作介紹了、
好比咱們有個Test 實體類 對應的數據庫的母表名稱 爲 test 而咱們要保存到子表的 test_01要怎麼作呢?
[java] view plain copy
- public void saveTest(Test test){
-
- SessionFactory sf = super.getHibernateTemplate().getSessionFactory();//獲取session工廠
-
- MyInterceptor interceptor = new MyInterceptor();//咱們的攔截器
-
- interceptor.setTargetTableName("test");//要攔截的目標表名
-
- interceptor.setTempTableName("test_01"); //要替換的子表名
-
- Session session = sf.openSession(interceptor);//當前的session使用這個攔截器
-
- try{
-
- Transaction tx = session.beginTransaction();//獲取事務
- tx.begin();//開啓事務
- session.saveOrUpdate(test);//保存和更新
- tx.commit();//提交
-
- }catch(Exception e){
- e.printStackTrace();
- }finally{
- session.close();
- }
-
- }
這樣就能把信息存到子表test_01裏啦、並且根本沒人察覺咱們的"使壞"、hibernate還老老實實的本份的作本身的工做呢、
CURD動做就這樣被咱們"使壞"着、
那咱們老是new 出來 咱們的攔截器 多麼費勁啊、若是我還須要其餘的地方還須要分表的地方、難道我還要再次new出來給多個地方用?
這樣咱們就在spring裏多加一個bean 指向咱們的class類
[plain] view plain copy
- <bean id="MyInterceptor" class="cn.test.MyInterceptor"/>
而後攔截器從spring拿就能夠了、在setter進去目標表名和替換表名、
咱們項目是web.xml加載了一個實現ApplicationContextAware類的一個類
static 的 ApplicationContext applicationContext 從裏面getBean 就能拿到了
這樣就ok啦、