Springでのマルチデータベース読み出しの構成

4520 ワード

多数のユーザの読み取りに対応するシステムでは、通常、データベースの操作は読み書き分離方式を採用し、1つのデータベースに書き込み、コピーによって他の複数のデータベースにデータを同期させ、これらのデータベースから読み書き操作を行い、springを用いて複数のデータベースを構成する場合、複数のデータSourceからのデータベース接続を直接サポートすることはできない.このためにはjavaxを実現するDataSourceのエージェントを開発する必要がある.sql.DataSourceインタフェース.このエージェントは、あるポリシーに従って既存の複数のDataSourceから1つを選択し、データ・アクセス・レイヤで使用できるSessionFactoryに提供します.原理は下図の通りです.
DataSource ProxyがDataSourceを選択する方法は、実際に設計することができます.ここでは簡単なので、ランダムな方法で1つを選択します.ソースコードは次のとおりです.
package code;

import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.SQLException;

import java.util.List;
import java.util.Random;

import javax.sql.DataSource;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class RandomDataSource  implements DataSource {

	private List dataSourcePool ;
	protected Log log =  LogFactory.getLog(getClass());
	
	private  static ThreadLocal dsHolder = new ThreadLocal();
	
	
	/**
	 *    DataSource       
	 *
	 *
	 */
	private DataSource randomDs(){
		
		int size = dataSourcePool.size();
		
		Random r= new Random();
		
		int t = r.nextInt(size);
		
		dsHolder.set(dataSourcePool.get(t));
		return dsHolder.get();
		
		
	}
	
	
	@Override
	public Connection getConnection() throws SQLException {
		
		Connection conn = randomDs().getConnection();
		log.info("conn URL---->"+conn.getMetaData().getURL());
		return conn;
	}

	@Override
	public Connection getConnection(String username, String password)
			throws SQLException {
		// TODO Auto-generated method stub
		
		Connection conn = randomDs().getConnection(username, password);
		
		
		return conn;
	}

	@Override
	public PrintWriter getLogWriter() throws SQLException {
		
		return dsHolder.get().getLogWriter();
	}

	@Override
	public int getLoginTimeout() throws SQLException {
		// TODO Auto-generated method stub
		return dsHolder.get().getLoginTimeout();
	}

	@Override
	public void setLogWriter(PrintWriter out) throws SQLException {
		// TODO Auto-generated method stub
		dsHolder.get().setLogWriter(out);
	}

	@Override
	public void setLoginTimeout(int seconds) throws SQLException {
		// TODO Auto-generated method stub
		dsHolder.get().setLoginTimeout(seconds);
	}

	@Override
	public boolean isWrapperFor(Class> iface) throws SQLException {
		// TODO Auto-generated method stub
		return dsHolder.get().isWrapperFor(iface);
	}

	@Override
	public  T unwrap(Class iface) throws SQLException {
		// TODO Auto-generated method stub
		return dsHolder.get().unwrap(iface);
	}

	public List getDataSourcePool() {
		return dataSourcePool;
	}

	public void setDataSourcePool(List dataSourcePool) {
		
		this.dataSourcePool = dataSourcePool;
	}

}

可用性のため、実際の本番環境では、取得したデータソースに対応するデータベースがアクセス可能かどうかを判断し、アクセスできない場合は、他の利用可能なデータソースを取得する必要があります.
スプリングフレームでの構成は次のとおりです.

 		
 			
 				
 				
 			
 		
 	
 	
	
	
		
		
		
		
	
	
	 
		
		
		
		
	
	
	
	
	
		
			
				org.hibernate.dialect.MySQLDialect
				true
				true
				
			
		
		
		
		
	

ここにはMySQLデータベースが接続されています.他のデータベースであれば、DataSource 1とDataSource 2のパラメータとhibernateが必要です.dialectはそれに応じて修正します.