spring从3.1.0升级到4.2.7

阅读更多

项目有一个表由于业务猛增,需要分表,分表之后就必然用到动态查询表。

项目框架为spring+springMVC+hibernate,通过重写hibernate拦截器EmptyInterceptor可以实现动态表映射。因为spring-orm还用的是3.1.0,它的LocalSessionFactoryBean不支持entityInterceptor属性,因此需要升级spring版本到4.x,这次按照网上的方法升级到了4.2.7。

 

1 spring依赖

 


        UTF-8
        2.5.1
        4.2.7.RELEASE
        3.0.5.RELEASE
        4.3.8.Final


 

            org.springframework
            spring-core
            ${spring.version}
            
                
                    commons-logging
                    commons-logging
                
            
        
        
            org.springframework
            spring-beans
            ${spring.version}
        
        
            org.springframework
            spring-context
            ${spring.version}
        
        
            org.springframework
            spring-context-support
            ${spring.version}
        
        
            org.springframework
            spring-aop
            ${spring.version}
            
                
                    commons-logging
                    commons-logging
                
            
        
        
            org.springframework
            spring-tx
            ${spring.version}
        
        
            org.springframework
            spring-test
            ${spring.version}
        
        
            org.springframework
            spring-orm
            ${spring.version}
        
        
            org.springframework
            spring-jdbc
            ${spring.version}
        
        
            org.springframework
            spring-oxm
            ${spring.version}
        
        
            org.springframework
            spring-web
            ${spring.version}
        
        
            org.springframework
            spring-webmvc
            ${spring.version}
        
  

    com.fasterxml.jackson.core
    jackson-core
    ${jackson.version}


    com.fasterxml.jackson.core
    jackson-databind
    ${jackson.version}


    com.fasterxml.jackson.core
    jackson-annotations
    ${jackson.version}


    com.fasterxml.jackson.module
    jackson-module-jaxb-annotations
    ${jackson.version}

 

 

项目里还用到了spring-security,本来想一起升级,但是改动太大,最后还是沿用了之前的版本,等以后有时间再研究一下。

注意:这里需要把jackson也升级。

 

2 修改springmvc.xml,使用MappingJackson2HttpMessageConverter代替MappingJacksonHttpMessageConverter,MappingJackson2JsonView代替MappingJacksonJsonView。

 

3 修改spring.xml,在LocalSessionFactoryBean中加入entityInterceptor属性。

 

 
    
        
        
            
        
        
            
        
 

            
                
                after_transaction

                
                    org.springframework.orm.hibernate4.SpringSessionContext
                
                ${hibernate.dialect}
                ${hibernate.show_sql}
                ${hibernate.generate_statistics}
                ${hibernate.hbm2ddl.auto}
                ${hibernate.jdbc.batch_size}
                after_transaction
                false
                false
            
        
    

 

 

4 下面就是重写的hibernate拦截器

 

package com.eversec.base.base;

import org.hibernate.EmptyInterceptor;

/**
 * 重写Hibernate拦截器
 * 实现动态替换表名和添加时忽略重复记录
 *
 * @author gb
 * @version 2015-01-13
 */
public class BaseInterceptor extends EmptyInterceptor {

    private static final long serialVersionUID = 1L;


    /**
     * 动态替换表名
     */
    public static final String REPLACE_TABLE_NAME = "replace_table_name";
    /**
     * insert时添加ignore
     */
    public static final String ADD_IGNORE = "add_ignore";
    /**
     * insert时添加ignore并动态替换表名
     */
    public static final String ADD_IGNORE_AND_REPLACE_TABLE_NAME = "add_ignore_replace_table_name";

    // 使用ThreadLocal存放日期,保证每个线程取到自己需要动态替换表命的日期
    private static ThreadLocal thread = new ThreadLocal();

    /**
     * 存放SQL替换内容
     *
     * @param contents [0]关键词,[1]被替换内容,[2]替换内容
* 1)关键词replace_table_name,替换表名
* 2)关键词add_ignore,insert into时添加ignore
* 3)关键词add_ignore_replace_table_name,insert into时添加ignore并替换表名
*/ public static void replace(String... contents) { thread.set(contents); } /** * SQL替换内容 *

* [0]关键词,[1]被替换内容,[2]替换内容
* 1)关键词replace_table_name,替换表名
* 2)关键词add_ignore,insert into时添加ignore
* 3)关键词add_ignore_replace_table_name,insert into时添加ignore并替换表名
* 4)替换内容为空时,不处理SQL并返回 *

*/ public String onPrepareStatement(String sql) { String[] contents = thread.get(); if (contents == null || contents.length < 1) { return sql; } if (contents[0].equals(REPLACE_TABLE_NAME)) { sql = replaceTableName(sql, contents[1], contents[2]); } else if (contents[0].equals(ADD_IGNORE)) { sql = addIgnore(sql); } else if (contents[0].equals(ADD_IGNORE_AND_REPLACE_TABLE_NAME)) { sql = addIgnoreAndReplaceTableName(sql, contents[1], contents[2]); } thread.remove(); //System.out.println(sql); return sql; } // 动态替换表名 private String replaceTableName(String sql, String oldContent, String replaceContent) { sql = sql.replaceAll(oldContent, replaceContent); return sql; } // insert忽略重复记录 private String addIgnore(String sql) { sql = sql.replaceAll("insert into", "insert ignore into"); return sql; } // insert忽略重复记录同时替换表名 private String addIgnoreAndReplaceTableName(String sql, String oldContent, String replaceContent) { sql = sql.replaceAll("insert into", "insert ignore into"); return replaceTableName(sql, oldContent, replaceContent); } }

 

 

5 最后,怎么使用呢?不用关注微信号,马上告诉你答案。

    使用起来相当的简单,只要在service或者dao层执行库操作前调用 BaseInterceptor.replace(BaseInterceptor.REPLACE_TABLE_NAME,"black_list_phone", "black_list_phone_" + groupId);即可。其中black_list_phone是模板表,groupId是我的逻辑分组,如果是1,就从black_list_phone直接映射到black_list_phone_1。

private void replaceTable(Integer groupId) {
        BaseInterceptor.replace(BaseInterceptor.REPLACE_TABLE_NAME,
                "black_list_phone", "black_list_phone_" + groupId);
    }

public void save(BlackListPhone entity, Integer groupId) {
    replaceTable(groupId);
    super.save(entity);
}

 

你可能感兴趣的:(spring从3.1.0升级到4.2.7)