Springでのマルチデータベース読み出しの構成
多数のユーザの読み取りに対応するシステムでは、通常、データベースの操作は読み書き分離方式を採用し、1つのデータベースに書き込み、コピーによって他の複数のデータベースにデータを同期させ、これらのデータベースから読み書き操作を行い、springを用いて複数のデータベースを構成する場合、複数のデータSourceからのデータベース接続を直接サポートすることはできない.このためにはjavaxを実現するDataSourceのエージェントを開発する必要がある.sql.DataSourceインタフェース.このエージェントは、あるポリシーに従って既存の複数のDataSourceから1つを選択し、データ・アクセス・レイヤで使用できるSessionFactoryに提供します.原理は下図の通りです.
DataSource ProxyがDataSourceを選択する方法は、実際に設計することができます.ここでは簡単なので、ランダムな方法で1つを選択します.ソースコードは次のとおりです.
可用性のため、実際の本番環境では、取得したデータソースに対応するデータベースがアクセス可能かどうかを判断し、アクセスできない場合は、他の利用可能なデータソースを取得する必要があります.
スプリングフレームでの構成は次のとおりです.
ここにはMySQLデータベースが接続されています.他のデータベースであれば、DataSource 1とDataSource 2のパラメータとhibernateが必要です.dialectはそれに応じて修正します.
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はそれに応じて修正します.