zookeeper 数据源动态配置
zookeeper具体实现配置在这里不具体描述,可查看zookeper配置一、实现的方式数据库的连接都会从在数据源datasource,对数据库的连接或者连接池的具体配置都在其中,因此,我们在修改数据库的配置的同时修改datasource 就可以不需要重新启动项目而实现数据库的切换。使用org.apache.commons.dbcp.BasicDataSource说明:这是一种推荐说明的数据源
·
zookeeper具体实现配置在这里不具体描述,可查看zookeper配置
一、实现的方式
数据源datasource,数据库的连接或者连接池的具体配置都在其中,因此,我们在修改数据库的配置的同时修改datasource 就可以不需要重新启动项目而实现数据库的切换。
使用org.apache.commons.dbcp.BasicDataSource
说明:这是一种推荐说明的数据源配置方式,它真正使用了连接池技术
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName">
<value>oracle.jdbc.driver.OracleDriver</value>
</property>
<property name="url">
<value>jdbc:oracle:thin:@localhost:1521:orcl</value>
</property>
<property name="username">
<value>test</value>
</property>
<property name="password">
<value>test</value>
</property>
<property name="maxActive">
<value>255</value>
</property>
<property name="maxIdle">
<value>2</value>
</property>
<property name="maxWait">
<value>120000</value>
</property>
</bean>
spring 加载容器的时候初始化了dataSource,为了方便操作dataSource,我重写了dataSource,重新了dataSource的创建,以及添加了dataSource的修改。
package app.datasource;
import app.context.RuntimeContext;
import app.utils.JackSonUtil;
import app.utils.PropertiesUtil;
import app.utils.ValueUtil;
import app.zookeeper.ConfigureUtil;
import org.apache.commons.dbcp.BasicDataSource;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.commons.pool.impl.GenericKeyedObjectPool;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.util.Map;
import java.util.Properties;
import java.util.logging.Logger;
/**
* Created by lili19289 on 2016/8/23.
*/
public class DataSourceConfigure extends BasicDataSource{
public static final String PREFFIX = "db.";
public static final String PROP_KEY_DRIVERCLASSNAME =PREFFIX+ "driver";
public static final String PROP_KEY_URL = PREFFIX+"url";
public static final String PROP_KEY_USERNAME =PREFFIX+ "username";
public static final String PROP_KEY_PASSWORD = PREFFIX+"password";
public static final String PROP_KEY_MAXACTIVE = PREFFIX+"maxActive";
public static final String PROP_KEY_INITIALSIZE = PREFFIX+"initialSize";
public static final String PROP_KEY_MAXWAIT =PREFFIX+ "maxWait";
public static final String PROP_KEY_MAXIDLE = PREFFIX+"maxIdle";
public static final String PROP_KEY_MINIDLE = PREFFIX+"minIdle";
public static final String PROP_KEY_TIMEBETWEENEVICTIONRUNSMILLS = PREFFIX+"timeBetweenEvictionRunsMillis";
public static final String PROP_KEY_MINEVICTABLEIDLETIMEMILLIS = PREFFIX+"minEvictableIdleTimeMillis";
private static final Log LOG = LogFactory.getLog(DataSourceConfigure.class);
private static Properties prop;
public Connection getConnection() throws SQLException {
return this.getDataSource().getConnection();
}
public DataSource getDataSource (){
initDataSource();
try {
this.dataSource= this.createDataSource();
} catch (SQLException e) {
e.printStackTrace();
}
return this.dataSource;
}
public void initDataSource(){
Map<String,Object > configureData = ConfigureUtil.loadConfigData("db");
System.err.println(configureData.get(PROP_KEY_DRIVERCLASSNAME).toString());
this.setDriverClassName(configureData.get(PROP_KEY_DRIVERCLASSNAME).toString());
this.setUrl(configureData.get(PROP_KEY_URL).toString());
this.setUsername(configureData.get(PROP_KEY_USERNAME).toString());
this.setPassword(configureData.get(PROP_KEY_PASSWORD).toString());
int initialSize = ValueUtil.getInt(configureData.get(PROP_KEY_INITIALSIZE), -1);
if (-1 == initialSize) {
initialSize = this.initialSize;
}
this.setInitialSize(initialSize);
// maxActive
int maxActive = ValueUtil.getInt(configureData.get(PROP_KEY_MAXACTIVE), -1);
if (-1 == maxActive) {
maxActive = this.maxActive;
}
this.setMaxActive(maxActive);
// maxIdle
int maxIdle = ValueUtil.getInt(configureData.get(PROP_KEY_MAXIDLE), -1);
if (-1 == maxIdle) {
maxIdle = this.maxIdle;
}
this.setMaxIdle(maxIdle);
// minIdle
int minIdle = ValueUtil.getInt(configureData.get(PROP_KEY_MINIDLE), -1);
if (-1 == minIdle) {
minIdle = this.minIdle;
}
this.setMinIdle(minIdle);
// maxWait
long maxWait = ValueUtil.getLong(configureData.get(PROP_KEY_MAXWAIT), -1);
if (-1 == maxWait) {
maxWait = this.maxWait;
}
this.setMaxWait(maxWait);
// timeBetweenEvictionRunsMillis
long timeBetweenEvictionRunsMillis = ValueUtil.getLong(configureData.get(PROP_KEY_TIMEBETWEENEVICTIONRUNSMILLS),
-1);
if (-1 == timeBetweenEvictionRunsMillis) {
timeBetweenEvictionRunsMillis = this.timeBetweenEvictionRunsMillis;
}
this.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
// minEvictableIdleTimeMillis
long minEvictableIdleTimeMillis = ValueUtil.getLong(configureData.get(PROP_KEY_MINEVICTABLEIDLETIMEMILLIS), -1);
if (-1 == minEvictableIdleTimeMillis) {
minEvictableIdleTimeMillis = this.minEvictableIdleTimeMillis;
}
this.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
}
public static void changeDataSource(){
DataSourceConfigure dataSourceConfigure = (DataSourceConfigure) RuntimeContext.getBean("dataSource");
try {
dataSourceConfigure.close();
dataSourceConfigure.initDataSource();
} catch (SQLException e) {
e.printStackTrace();
}
}
public Logger getParentLogger() throws SQLFeatureNotSupportedException {
return null;
}
public <T> T unwrap(Class<T> iface) throws SQLException {
return null;
}
public boolean isWrapperFor(Class<?> iface) throws SQLException {
return false;
}
}
修改后,配置文件中的数据源使用重写过的数据库实体类,修改为:
<bean id="dataSource"class="app.datasource.DataSourceConfigure"
destroy-method="close">
</bean>
因此,当你修改数据库的配置时,调用changeDataSource()方法,关闭之前的数据源并初始化新的数据源,即可实现数据库的动态切换。这个方法放入zookeeper的监听器中便可实现分布式管理项目的数据库,而且不需要重启项目。
更多推荐
已为社区贡献1条内容
所有评论(0)