在spring中配置多数据库读取
在应对大量用户读取的系统中,对数据库的操作通常采用读写分离方式,往一个数据库写入,然后通过复制将数据同步到另外的多个数据库中,读操作都从这些数据库中操作,在采用spring来配置多数据库时,并不能直接支持从多个DataSource中获得数据库连接,为此需要开发一个DataSource的代理,代理实现javax.sql.DataSource接口。该代理根据一定的策略从已有的多个DataSource中选择一个,提供给SessionFactory,供数据访问层使用。原理如下图所示:DataSource Proxy选择DataSource的方式可以根据实际进行设计,这里为简单,就采用随机方式选择一个。源代码如下:
[java] view plaincopy
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 {
<span style="white-space:pre"> </span>private List<DataSource> dataSourcePool ;
<span style="white-space:pre"> </span>protected Log log = LogFactory.getLog(getClass());
<span style="white-space:pre"> </span>
<span style="white-space:pre"> </span>private static ThreadLocal<DataSource> dsHolder = new ThreadLocal<DataSource>();
<span style="white-space:pre"> </span>
<span style="white-space:pre"> </span>
<span style="white-space:pre"> </span>/**
<span style="white-space:pre"> </span> * 从已有DataSource中随机选择一个
<span style="white-space:pre"> </span> *
<span style="white-space:pre"> </span> *
<span style="white-space:pre"> </span> */
<span style="white-space:pre"> </span>private DataSource randomDs(){
<span style="white-space:pre"> </span>
<span style="white-space:pre"> </span>int size = dataSourcePool.size();
<span style="white-space:pre"> </span>
<span style="white-space:pre"> </span>Random r= new Random();
<span style="white-space:pre"> </span>int t = r.nextInt(size);
<span style="white-space:pre"> </span>dsHolder.set(dataSourcePool.get(t));
<span style="white-space:pre"> </span>return dsHolder.get();
<span style="white-space:pre"> </span>
<span style="white-space:pre"> </span>
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>
<span style="white-space:pre"> </span>
<span style="white-space:pre"> </span>@Override
<span style="white-space:pre"> </span>public Connection getConnection() throws SQLException {
<span style="white-space:pre"> </span>
<span style="white-space:pre"> </span>Connection conn = randomDs().getConnection();
<span style="white-space:pre"> </span>return conn;
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>@Override
<span style="white-space:pre"> </span>public Connection getConnection(String username, String password)
<span style="white-space:pre"> </span>throws SQLException {
<span style="white-space:pre"> </span>Connection conn = randomDs().getConnection(username, password);
<span style="white-space:pre"> </span>log.info("conn URL---->"+conn.getMetaData().getURL());
<span style="white-space:pre"> </span>
<span style="white-space:pre"> </span>return conn;
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>@Override
<span style="white-space:pre"> </span>public PrintWriter getLogWriter() throws SQLException {
<span style="white-space:pre"> </span>
<span style="white-space:pre"> </span>return dsHolder.get().getLogWriter();
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>@Override
<span style="white-space:pre"> </span>public int getLoginTimeout() throws SQLException {
<span style="white-space:pre"> </span>
<span style="white-space:pre"> </span>return dsHolder.get().getLoginTimeout();
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>@Override
<span style="white-space:pre"> </span>public void setLogWriter(PrintWriter out) throws SQLException {
<span style="white-space:pre"> </span>
<span style="white-space:pre"> </span>dsHolder.get().setLogWriter(out);
<span style="white-space:pre">