动态切换数据库不用重启服务器

做一个项目可能会用到多个数据库开发一套,测试一套遇到问题可能连接数据库时要换来换去,要去改配置重启 我觉得十分麻烦,所以自己做了一个动态切换数据库的空能 先上代码
public class MultiDataSourceAction extends BaseAction {
...
	private String url;
	public void setUrl(String url){
		this.url=url;
	}
	public String getUrl(){
		return url;
	}
	/**
	 * 切换数据库
	 * @return
	 * @throws Exception
	 */
	public String changeDataSource() throws Exception{
		this.addActionMessage("连接成功");
		String beanName="dataSource";//默认105 要与spring配置文件配置bean id相同
		if("11".equals(url)){
			beanName="dataSource11";
		}else if ("116".equals(url)) {
			beanName="dataSource116";
		}
		TabDataSource.getInstance().changeDataSource(beanName);
		return "success";
	}
...
}
这是action代码  需要从页面传过来一个区分那个数据库的标识
public class TabDataSource{
	public static TabDataSource NEWSOURCE=null;
	public SessionFactory factory;

	public static TabDataSource getInstance() throws Exception{
		if(NEWSOURCE==null)
		NEWSOURCE=new TabDataSource();
		SessionManager.releaseSession();//释放登录用户让其好重新登录 SessionManager是一个session管理,关于session资源的持久化应该统一在此类 就不上代码了
		return NEWSOURCE;
	}
	//new Configuration().configure().buildSessionFactory(); 
	public void changeDataSource(String beanName)throws Exception{
		//清除所有二级缓存 SourceTemplate是一个获得各种静态资源的类 大伙应该能想得到
		factory=(SessionFactory)SourceTemplate.getSpringContextInstance().getBean("sessionFactory");
		factory.evictQueries();
		//切换数据源
		HotSwappableTargetSource swapper=(HotSwappableTargetSource)SourceTemplate.getSpringContextInstance().getBean("swappableDataSource");
		DataSource newDataSource=(DataSource)SourceTemplate.getSpringContextInstance().getBean(beanName);
		swapper.swap(newDataSource);
		// 重新加载菜单
//到这切换数据源算是完成了 下面的主要是我的项目里 在服务器启动的时候就初始化了一个servlet用来加载菜单所以要重新加载 
		ICache cache=(ICache)SourceTemplate.getSpringContextInstance().getBean("BaseSystemCache");
		cache.getCachMap().clear();
		cache.cacheInit();
		CacheManager.addCache(cache.getCachName(), cache);
	}

}

切换数据源在上面完成 下面看配置
<bean id="sessionFactory"
     class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
     	<property name="dataSource">
     		<ref local="swappable"/>
     	</property>....
     	</bean>
 <bean id="swappable" class="org.springframework.aop.framework.ProxyFactoryBean">   
        <property name="targetSource">   
            <ref local="swappableDataSource"/>   
        </property>   
    </bean>
    <bean id="swappableDataSource" class="org.springframework.aop.target.HotSwappableTargetSource">   
        <constructor-arg>   
            <ref local="dataSource"/>   
        </constructor-arg>   
    </bean>
<bean id="propertyConfigurer"
		class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
		<property name="locations">
			<list>
				<value>
					SqlMapConfig.properties
				</value>
			</list>
		</property>
	</bean>
	<bean id="dataSource"
		class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
		<property name="driverClassName">
			<value>${jdbc.driverClassName}</value>
		</property>
		<property name="url">
			<value>${jdbc.url}</value>
		</property>
		<property name="username">
			<value>${jdbc.username}</value>
		</property>
		<property name="password">
			<value>${jdbc.password}</value>
		</property>
	</bean>
	<bean id="dataSource11"
		class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
		<property name="driverClassName">
			<value>${jdbc.driverClassName}</value>
		</property>
		<property name="url">
			<value>${jdbc.11url}</value>
		</property>
		<property name="username">
			<value>${jdbc.username}</value>
		</property>
		<property name="password">
			<value>${jdbc.password}</value>
		</property>
	</bean>
	<bean id="dataSource116"
		class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
		<property name="driverClassName">
			<value>${jdbc.driverClassName}</value>
		</property>
		<property name="url">
			<value>${jdbc.116url}</value>
		</property>
		<property name="username">
			<value>${jdbc.username}</value>
		</property>
		<property name="password">
			<value>${jdbc.password}</value>
		</property>
	</bean>

到这就差不多了还需要个SqlMapConfig.properties就OK了 因为我所用的库就URL不同 其他的都是一样的 所以上面的配置大伙可以根据自己要求改
jdbc.datasource=org.apache.commons.dbcp.BasicDataSource
jdbc.driverClassName=com.ibm.db2.jcc.DB2Driver
jdbc.url=jdbc\:db2\://ip\:post/dbname
jdbc.username=username
jdbc.password=password
jdbc.105url=jdbc\:db2\://ip\:post/dbname
jdbc.116url=jdbc\:db2\://ip\:post/dbname
jdbc.11url=jdbc\:db2\://ip\:post/dbname

上面是SqlMapConfig.properties 配置
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
        "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
        "http://struts.apache.org/dtds/struts-2.0.dtd">

<struts>	
	<package name="multi" namespace="/bbsp/bd" extends="leadmind-base">
    	<!-- -->
    	<global-results>
    		<result name="commonException">/billplatform/exceptions/exception.jsp</result>
    	</global-results>
		<global-exception-mappings>
			<exception-mapping result="commonException" exception="java.lang.Exception"></exception-mapping>		
		</global-exception-mappings>
		 
		<action name="MultiDataSource_*" method="{1}" class="***.actions.MultiDataSourceAction">
			<result name="success">/success.jsp</result>
		</action>
	</package>
</struts>

自己做这个感触很多  通过做这个小功能 对hibernate spring 了解又深了一些 但也遇到了很多问题 我通过spring 通过setter注入sessionfactory时怎么也注入不进去现在还不明白 但注入一些常量又可以 现在还不明白 只能用getbean方法..这个功能是完成了 但不知道效率咋样 请大家指点

你可能感兴趣的:(spring,jdbc,struts,db2,配置管理)