博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
使用hibernate 分表做增删改查、
阅读量:2228 次
发布时间:2019-05-09

本文共 3477 字,大约阅读时间需要 11 分钟。

公司项目有一张表的数据量特别大、而且时间越长累积的数据量就越大、

 

后来DBA决定分表来解决性能问题、

 

分表是指   一个母体表  一群子表(结构和字段与母体表完全一样) 我们程序对母表操作其实就是对子表操作、让其无法感知有分表这个动作、

 

而使用hibernate如何分表呢?

 

难道我要写N个子表类Domain吗?那累屎我算了、

 

呵呵、我们这里需要hibernate一个拦截器类  org.hibernate.EmptyInterceptor

 

这个拦截器做了什么呢?

 

hibernate最终会将我们写的HQL语句转换成SQL语句、而当转换SQL且没放如数据库执行的时候、被拦截器就拦住啦、我们就可以偷偷的"使坏"啦、

 

我们需要一个自己的类来继承org.hibernate.EmptyInterceptor

 

[java]
  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. }  
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]
  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.    }  
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]
  1. <bean id="MyInterceptor" class="cn.test.MyInterceptor"/>  

然后拦截器从spring拿就可以了、在setter进去目标表名和替换表名、

 

 我们项目是web.xml加载了一个实现ApplicationContextAware类的一个类 

 

static 的 ApplicationContext applicationContext  从里面getBean 就能拿到了

 

这样就ok啦、

 

转载地址:http://lsgfb.baihongyu.com/

你可能感兴趣的文章
google app api相关(商用)
查看>>
linux放音乐cd
查看>>
GridView+存储过程实现'真分页'
查看>>
flask_migrate
查看>>
解决activemq多消费者并发处理
查看>>
UDP连接和TCP连接的异同
查看>>
hibernate 时间段查询
查看>>
java操作cookie 实现两周内自动登录
查看>>
Tomcat 7优化前及优化后的性能对比
查看>>
Java Guava中的函数式编程讲解
查看>>
Eclipse Memory Analyzer 使用技巧
查看>>
tomcat连接超时
查看>>
谈谈编程思想
查看>>
iOS MapKit导航及地理转码辅助类
查看>>
检测iOS的网络可用性并打开网络设置
查看>>
简单封装FMDB操作sqlite的模板
查看>>
iOS开发中Instruments的用法
查看>>
强引用 软引用 弱引用 虚引用
查看>>
数据类型 java转换
查看>>
"NetworkError: 400 Bad Request - http://172.16.47.117:8088/rhip/**/####t/approval?date=976
查看>>