AbstractDataSourceに基づいて、メインデータベースの切り替えを実現します。

5937 ワード

もっと読む
AbstractDataSourceに基づいて、メインデータベースの切り替えを実現します。
プロジェクトの背景:
1.DBAはあるSQLの運転に重大なタイムアウトを通知し、読み取り元をメインライブラリからライブラリに変更し、メインライブラリの圧力を軽減することを知らせる。
2.データベース構成には2つのデータソースがあり、主に2つの構成からなる。
メインライブラリ:読み書きが許可されます。ライブラリ:読むだけ許可します。
メインライブラリデータ同期
3.機能はすでに存在しています。分析運行の流れは以下の通りです。
プロジェクトの流れ:
一、カスタムコメントを使う

    @RequestMapping(value="/getBrandHisProjectsForM",method=RequestMethod.POST)
    @ResponseBody
    @DbReadonly
    public Response getBrandHisProjectsForM(@RequestBody BrandHisProjectReq brandHisProjectReq){
    	return getBrandHisProjects(brandHisProjectReq.getBrandId(), brandHisProjectReq.getCpage(), brandHisProjectReq.getPageSize(), ConstantAction.PLATFORM.M);
    }

1.Service層またはService層のメソッドを呼び出す上で@DbReadonlyコメントを追加する。
2.以下のSQLを読むデータソースをこの注釈で識別すると、データベースから接続されます。
二、カスタムコメント

//         
@Retention(RetentionPolicy.RUNTIME)
//              
@Target(ElementType.METHOD)
//     
@Documented
public @interface DbReadonly {
        //    :readonly ,      、                 	
	String value() default "readonly";	
}
三、Springカット面注入

@Aspect
@Component
public class DataSourceAspect {
	
        //        
	@Pointcut("@annotation(com.xxx.lang.annotation.DbReadonly)")
	public void dbAspect() {
	}
	
        //                
        @Before("dbAspect()")    
        public void before(JoinPoint joinPoint) {
		DbContextHolder.setReadonly();
        }

        //                
	@After("dbAspect()")
	public void after(JoinPoint joinPoint) {
		DbContextHolder.setMaster();
	}
}


四、現在のデータソースの設定を読み込みます。

public class DbContextHolder {
	
    /**
     *      
     */
    private static final ThreadLocal contextHolder = new ThreadLocal();
    
    /**
     *          
     * 
     * @param dbType
     */
    public static void setDbType(String dbType) {
        contextHolder.set(dbType);
    }
    
    /**
     *          
     * 
     * @return
     */
    public static String getDbType() {
        return ((String) contextHolder.get());
    }
    
    /**
     *          
     * 
     * @return
     */
    public static void clearDbType() {
        contextHolder.remove();
    }
    
    /**
     *     
     */
	public static void setMaster() {
		clearDbType();
	}
	
	/**
     *     
     */
	public static void setReadonly() {
		setDbType("readonly");
	}
    
}

五、Spring-mybatis.xml配置は動的にデータソースを取得する

    
         
        
        
        
            
            
        
        
        
    


六、現在のデータソースの設定を動的に読み取る


public class DynamicDataSource extends AbstractRoutingDataSource {
	
    /**
     *        
     */
    @Override
    protected Object determineCurrentLookupKey() {
        String obj = DbContextHolder.getDbType();
        if (obj == null || obj.equalsIgnoreCase("default")) {
            return "master";
        } else {
            return obj;
        }
    }
    
}

七、データベース選択ブロック


//         ,      
public class DbSelectFilter implements Filter {

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        DbContextHolder.setDbType("defalut");
        chain.doFilter(request, response);
    }

    @Override
    public void destroy() {

    }
}

八、Spring-mybatis.xmlロード

	
	
		p:dataSource-ref="dynDataSource" p:typeAliasesPackage="com.xxx.core.model,"
		p:mapperLocations="classpath*:com/**/mapping/*Mapper.xml">
		 
		

プロジェクトの実行:
1.各要求はブロックで処理され、デフォルトではメインライブラリを読み込むように処理されます。
2.サービス中の  methodには@DbReadonlyが使われています。  注記の場合、Springの切断面向けの表示
方法実行前に  データソースをライブラリに切り替え、メソッド実行後にメインライブラリに切り替えます。
プロジェクトのコメント:
1.このラベルを複数回使用してはいけません。つまり、Serviceを呼び出しているところ(外部から提供された呼び出しインターフェースは、ある特定の需要に対して処理し、複数のServiceインターフェースを同時に呼び出しています。)で使用してもいいです。Serviceで使用すると、切り替えが失敗します。
分析:
A呼び出しB
Aにこのラベルを使用してライブラリから
Bにこのラベルを使用して、ライブラリからBメソッドの実行が完了し、メインライブラリに切り替えます。
A受信B方法の戻り値
Aでは他の方法で動作しますが、他の方法でこのコメントがない場合、データソースはメインライブラリに切り替えられました。
A呼び出しが完了したら、メインライブラリに切り替えます。