使用SSH框架开发应用时,经常遇到需要配置多数据源的情况,下面说一下使用配置文件和注解的两种配置方式。
一、配置文件方式。
这种方式在比较早一点的项目里经常用到。在spring的配置文件中,按如下方式配置:
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" /><!-- 第一个数据源 -->
<property name="configLocations">
<list></list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
<prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
<!--
<prop key="hibernate.cache.use_query_cache">${hibernate.cache.use_query_cache}</prop>
<prop key="hibernate.cache.provider_class">${hibernate.cache.provider_class}</prop>
-->
</props>
</property>
<property name="mappingResourceServices">
<value>true</value>
</property>
</bean>
<bean id="sessionFactoryNews" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSourceNews" /><!-- 第二个数据源 -->
<property name="configLocations">
<list></list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
<prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
<!--
<prop key="hibernate.cache.use_query_cache">${hibernate.cache.use_query_cache}</prop>
<prop key="hibernate.cache.provider_class">${hibernate.cache.provider_class}</prop>
-->
</props>
</property>
<property name="mappingResourceServices">
<value>true</value>
</property>
</bean>
在Dao的配置文件中,分别注入不同的SessionFactory。
<bean id="iOrganProductDao" class="com.sitechasia.financial.remoteuser.dao.impl.OrganProductImpl">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<bean id="organNewsDao"
class="com.sitechasia.financial.remoteuser.dao.impl.OrganNewsDaoImpl">
<property name="sessionFactory" ref="sessionFactoryNews" />
</bean>
二、注解方式。
目前的项目基本都是采用注解了。
当自定义的Dao实现了org.springframework.orm.hibernate3.support.HibernateDaoSupport 时,若Dao是以注解的形式提供bean,则要以注解的形式注入SessionFactory,而HibernateDaoSupport 中相关的set方法都是final 的,即不能覆盖:
public final void setSessionFactory(SessionFactory sessionFactory) {
if (this.hibernateTemplate == null || sessionFactory != this.hibernateTemplate.getSessionFactory()) {
this.hibernateTemplate = createHibernateTemplate(sessionFactory);
}
}
public final void setHibernateTemplate(HibernateTemplate hibernateTemplate) {
this.hibernateTemplate = hibernateTemplate;
}
所以采用如下方式解决:
在spring配置文件中:
<!--第一个数据源-->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
destroy-method="close">
<property name="driverClass">
<value>${jdbc.driverClassName}</value>
</property>
<property name="jdbcUrl">
<value>${jdbc.url}</value>
</property>
<property name="user">
<value>${jdbc.username}</value>
</property>
<property name="password">
<value>${jdbc.password}</value>
</property>
<!--当连接池中的连接耗尽的时候c3p0一次同时获取的连接数。-->
<property name="acquireIncrement">
<value>${c3p0.acquireIncrement}</value>
</property>
<!--定义在从数据库获取新连接失败后重复尝试的次数。-->
<property name="acquireRetryAttempts">
<value>${c3p0.acquireRetryAttempts}</value>
</property>
<!--两次连接中间隔时间,单位毫秒。-->
<property name="acquireRetryDelay">
<value>${c3p0.acquireRetryDelay}</value>
</property>
<property name="initialPoolSize">
<value>${c3p0.initialPoolSize}</value>
</property>
<property name="testConnectionOnCheckout">
<value>${c3p0.testConnectionOnCheckout}</value>
</property>
<property name="minPoolSize">
<value>${c3p0.minPoolSize}</value>
</property>
<property name="maxPoolSize">
<value>${c3p0.maxPoolSize}</value>
</property>
<property name="maxIdleTime">
<value>${c3p0.maxIdleTime}</value>
</property>
<property name="idleConnectionTestPeriod">
<value>${c3p0.idleConnectionTestPeriod}</value>
</property>
<property name="maxStatements">
<value>${c3p0.maxStatements}</value>
</property>
<property name="numHelperThreads">
<value>${c3p0.numHelperThreads}</value>
</property>
</bean>
<!--第一个sessionFactory-->
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="namingStrategy">
<bean class="org.hibernate.cfg.ImprovedNamingStrategy" />
</property>
<property name="configurationClass" value="org.hibernate.cfg.AnnotationConfiguration"/>
<property name="packagesToScan">
<list>
<value>com.common.po</value>
<value>com.permission.po</value>
<value>com.opinion.po</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">
org.hibernate.dialect.MySQLDialect
</prop>
<prop key="hibernate.show_sql">false</prop>
<prop key="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</prop>
<prop key="hibernate.cache.provider_configuration_file_resource_path">${hibernate.ehcache_config_file}</prop>
<prop key="hibernate.cache.use_query_cache">true</prop>
</props>
</property>
</bean>
<!-- 第二个数据源 -->
<bean id="browserDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
destroy-method="close">
<property name="driverClass">
<value>${jdbc.browser.driverClassName}</value>
</property>
<property name="jdbcUrl">
<value>${jdbc.browser.url}</value>
</property>
<property name="user">
<value>${jdbc.browser.username}</value>
</property>
<property name="password">
<value>${jdbc.browser.password}</value>
</property>
<!--当连接池中的连接耗尽的时候c3p0一次同时获取的连接数。-->
<property name="acquireIncrement">
<value>${c3p0.acquireIncrement}</value>
</property>
<!--定义在从数据库获取新连接失败后重复尝试的次数。-->
<property name="acquireRetryAttempts">
<value>${c3p0.acquireRetryAttempts}</value>
</property>
<!--两次连接中间隔时间,单位毫秒。-->
<property name="acquireRetryDelay">
<value>${c3p0.acquireRetryDelay}</value>
</property>
<property name="initialPoolSize">
<value>${c3p0.initialPoolSize}</value>
</property>
<property name="testConnectionOnCheckout">
<value>${c3p0.testConnectionOnCheckout}</value>
</property>
<property name="minPoolSize">
<value>${c3p0.minPoolSize}</value>
</property>
<property name="maxPoolSize">
<value>${c3p0.maxPoolSize}</value>
</property>
<property name="maxIdleTime">
<value>${c3p0.maxIdleTime}</value>
</property>
<property name="idleConnectionTestPeriod">
<value>${c3p0.idleConnectionTestPeriod}</value>
</property>
<property name="maxStatements">
<value>${c3p0.maxStatements}</value>
</property>
<property name="numHelperThreads">
<value>${c3p0.numHelperThreads}</value>
</property>
</bean>
<!--第二个sessionFactory-->
<bean id="browserSessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="browserDataSource" />
<property name="namingStrategy">
<bean class="org.hibernate.cfg.ImprovedNamingStrategy" />
</property>
<property name="configurationClass" value="org.hibernate.cfg.AnnotationConfiguration"/>
<property name="packagesToScan">
<list>
<value>com.browser.po</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">
org.hibernate.dialect.MySQLDialect
</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</prop>
<prop key="hibernate.cache.provider_configuration_file_resource_path">${hibernate.ehcache_config_file}</prop>
<prop key="hibernate.cache.use_query_cache">true</prop>
</props>
</property>
</bean>
@Repository("websiteDao")
public class WebsiteDaoImpl extends BaseHibernateDao<Website, Long> implements WebsiteDao{
@Resource(name="browserSessionFactory")
private SessionFactory sessionFactory;
@PostConstruct
public void setMySessionFactory(){
super.setSessionFactory(sessionFactory);
}
}
即初始化时,调用setMySessionFactory()方法,把browserSessionFactory注入。这样不同的Dao可以使用不同的数据源了。