公司项目有一张表的数据量特别大、并且时间越长累积的数据量就越大、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啦、