• 使用hibernate 分表做增删改查


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

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

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

    而使用hibernate如何分表呢?

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

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

    这个拦截器做了什么呢?

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

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

    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要怎么做呢?

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



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

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

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

    这样就ok啦、

  • 相关阅读:
    一次完整的HTTP事务的过程
    移动端事件
    canvas 在视频中的用法
    理解Vue
    改变console.log的输出样式
    百度下拉搜索案例
    Vue总结
    字符串、正则
    .Net Mvc框架知识点
    Lowest Common Ancestor of a Binary Tree -- LeetCode
  • 原文地址:https://www.cnblogs.com/sunrunzhi/p/5195646.html
Copyright © 2020-2023  润新知