做一个项目可能会用到多个数据库开发一套,测试一套遇到问题可能连接数据库时要换来换去,要去改配置重启 我觉得十分麻烦,所以自己做了一个动态切换数据库的空能 先上代码
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方法..这个功能是完成了 但不知道效率咋样 请大家指点