简单方法实现SSH使用多数据源

前段时间,跟朋友讨论怎么实现这个东西的时候想到的一个方法,不知道正规场合可行不可行,我自己测试的时候没啥问题,我是个新手,希望朋友们不吝指教。

我测试的时候只是增删改查没啥问题,不知道事务是不是如我预料的那样没问题....

 

当然,做分布式还是用JTA更好一些,现在的JAVA EE容器都直接支持了,下面这些方法只是给像我一样的野战军用的土方法,适用于Tomcat,哈哈。

 

第一种(不推荐,因为无法实现分布式事务):
直接创建多个SessionFactory和多个DataSource,给他们赋予不同的id,在dao层使用的时候针对不同的数据库操作使用不同的sessionFactory


使用方法:

1、配置oracle数据源spring-oracle.xml:

 

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	     xmlns:aop="http://www.springframework.org/schema/aop"
	     xmlns:tx="http://www.springframework.org/schema/tx"
	     xmlns:context="http://www.springframework.org/schema/context"
	     xsi:schemaLocation="http://www.springframework.org/schema/beans
							 http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
					         http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
					         http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd
					         http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd"
         >
    
	<!-- 配置dataSource_oracle -->
	<bean id="dataSource_oracle" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
        <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/>
        <property name="url" value="jdbc:oracle:thin:@//218.198.177.109:1521/orcl"/>
        <property name="username" value="roy"/>
        <property name="password" value="roy"/>
        <property name="defaultAutoCommit" value="false"/>
	</bean>
	<!-- 配置sessionFactory_oracle -->
	<bean id="sessionFactory_oracle" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
		<property name="dataSource" ref="dataSource_oracle"/>
		<property name="hibernateProperties">
			<props>
				<!--
				<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
				-->
				<prop key="hibernate.dialect">org.hibernate.dialect.OracleDialect</prop>
				<prop key="hibernate.show_sql">true</prop>
				<prop key="hibernate.jdbc.fetch_size">30</prop>
				<prop key="hibernate.jdbc.batch_size">30</prop>
				<prop key="hibernate.hbm2ddl.auto">update</prop>
			</props>
		</property>
		<property name="annotatedClasses">
			<list>
				<value>model.User</value>
				<value>model.Role</value>
			</list>
		</property>
	</bean>
	
	<!-- 配置事务管理器 -->
	<bean id="transactionManager_oracle" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
		<property name="sessionFactory">
			<ref bean="sessionFactory_oracle"/>
		</property>	
	</bean>
	
	<!-- 配置事务的传播特性 -->
	<tx:advice id="txAdvice_oracle" transaction-manager="transactionManager_oracle">
		<tx:attributes>
			<tx:method name="add*" 		propagation="REQUIRED"/>
			<tx:method name="save" 		propagation="REQUIRED"/>
			<tx:method name="delete*" 	propagation="REQUIRED"/>
			<tx:method name="update*" 	propagation="REQUIRED"/>
			<tx:method name="*" 		propagation="REQUIRED"/>
		</tx:attributes>
	</tx:advice>
	
	<!-- 那些类的哪些方法参与事务 -->
	<aop:config>
		<aop:pointcut id="allManagerMethod_oracle" expression="execution(* service.*.*(..))"/>
		<aop:advisor pointcut-ref="allManagerMethod_oracle" advice-ref="txAdvice_oracle"/>
	</aop:config>
	
	<!--  使Spring关注Annotation  -->
   	<context:annotation-config /> 
   	<!--  让Spring通过自动扫描来查询和管理Bean  --> 
   	<context:component-scan  base-package ="*" />
   	
</beans>
 

 

2、配置mysql数据源spring-mysql:

跟oracle相同,只是去掉“配置注解进行实体映射那两行代码”:

<!--  使Spring关注Annotation  -->
   	<context:annotation-config /> 
   	<!--  让Spring通过自动扫描来查询和管理Bean  --> 
   	<context:component-scan  base-package ="*" />

事务传播特性要分开分别配置。

 

3、在Dao层使用SessionFactory

@Repository("stuDao")
public class StuDaoImpl extends HibernateDaoSupport implements StuDao {
	//注入HibernateSession,这里是关键,不同的dao使用不同的sessionFactory。
//当然,可以把这里抽象出来放到一个abstractDao里面,随意了。
	@Resource(name="sessionFactory_mysql")
	public void setSuperSessionFactory(SessionFactory sessionFactory){
        super .setSessionFactory(sessionFactory);
	}
	
	public void add(Stu stu) {
		this.getHibernateTemplate().save(stu);
	}

}

 现在,在Manager层调用dao的时候完全按照老套路走就行了,没什么特别的地方了。遗憾的是,这个方法只能够让不同的数据库使用不同的事务边界,无法实现分布式事务,只能在同时调用两个不同的数据库的地方加锁进行控制。

 

第二种(推荐,可以实现分布式事务管理):

之所以写道第二种,是因为原理跟第一种差不多....只是用到一个中间小组件而已。

就是使用jOTM来进行分布式事务管理,听说spring3.0已经不支持了,我不知道是不是真的,我用的是spring2.5进行的配置,感觉这么好用的东西应该不会不支持,大家有兴趣可以试一下spring3.x。

 

1、下载jOTM的包

将所有包拿到项目里,去掉重复包,如log4j.jar等。

 

2、配置spring-jOTM.xml

这个配置文件里也是同方法一相同,配置多个sessionFactory,只不过把这些sessionFactory都交给jOTM去管理,我们只去使用jOTM提供的那个就行了,类似于代理的东东。

 

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
	     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	     xmlns:aop="http://www.springframework.org/schema/aop"
	     xmlns:tx="http://www.springframework.org/schema/tx"
	     xmlns:context="http://www.springframework.org/schema/context"
	     xsi:schemaLocation="http://www.springframework.org/schema/beans
							 http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
					         http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
					         http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd
					         http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd"
         >
	
	<!--使用xapool连接池,共两个-->
	
	<bean id="dataSource_oracle" class="org.enhydra.jdbc.pool.StandardXAPoolDataSource" destroy-method="shutdown">
		<property name="dataSource">
		    <bean class="org.enhydra.jdbc.standard.StandardXADataSource" destroy-method="shutdown">
		      <property name="transactionManager" ref="jotm"/>
		      <property name="driverName" value="oracle.jdbc.driver.OracleDriver"/>
		      <property name="url" value="jdbc:oracle:thin:@//218.198.177.109:1521/orcl"/>
		    </bean>
		</property>
		<property name="user" value="roy"/>
		<property name="password" value="roy"/>
	</bean>
	<bean id="dataSource_mysql" class="org.enhydra.jdbc.pool.StandardXAPoolDataSource" destroy-method="shutdown">
		<property name="dataSource">
		    <bean class="org.enhydra.jdbc.standard.StandardXADataSource" destroy-method="shutdown">
		      <property name="transactionManager" ref="jotm"/>
		      <property name="driverName" value="com.mysql.jdbc.Driver"/>
		      <property name="url" value="jdbc:mysql://localhost:3306/stu"/>
		    </bean>
		</property>
		<property name="user" value="root"/>
		<property name="password" value="56906950"/>
	</bean>
	
	
	<!-- 定义sessionFactory,共两个-->
	
	<bean id="sessionFactory_oracle" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
		<property name="dataSource" ref="dataSource_oracle"/>
		<property name="annotatedClasses">
				<list>
					<value>model.User</value>
					<value>model.Role</value>
				</list>
		</property>
		<property name="hibernateProperties">
		    <props>
				<prop key="hibernate.dialect">org.hibernate.dialect.OracleDialect</prop>
				<prop key="hibernate.show_sql">true</prop>
				<prop key="hibernate.jdbc.fetch_size">30</prop>
				<prop key="hibernate.jdbc.batch_size">30</prop>
				<prop key="hibernate.hbm2ddl.auto">update</prop>
				<prop key="hibernate.connection.autocommit ">false</prop>
			</props>
		</property>
	</bean>
	<bean id="sessionFactory_mysql" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
		<property name="dataSource" ref="dataSource_mysql"/>
		<property name="annotatedClasses">
					<list>
						<value>model.Stu</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.jdbc.fetch_size">30</prop>
			  <prop key="hibernate.jdbc.batch_size">30</prop>
			  <prop key="hibernate.hbm2ddl.auto">update</prop>
		      <prop key="hibernate.connection.autocommit ">false</prop>
		    </props>
		</property>
	</bean>
	
	<!--声明jta   -->
    <bean id="jotm" class="org.springframework.transaction.jta.JotmFactoryBean"/>
    
    <!--定义jta事务管理器-->
	<bean id="tsManager" class="org.springframework.transaction.jta.JtaTransactionManager">
		<property name="userTransaction" ref="jotm"/>
	</bean>
	
	<!-- 配置事务传播特性 -->
	<tx:advice id="txAdvice" transaction-manager="tsManager">
		<tx:attributes>
		    <tx:method name="*" propagation="REQUIRED"/>
		</tx:attributes>
	</tx:advice>
	
	<!-- 那些类的哪些方法参与事务 -->
	<aop:config>
		<aop:advisor pointcut="execution(* service.*.*(..))" advice-ref="txAdvice"/>
	</aop:config>
	
	<!--  使Spring关注Annotation  -->
   	<context:annotation-config /> 
   	<!--  让Spring通过自动扫描来查询和管理Bean  --> 
   	<context:component-scan  base-package ="*" />
   	
</beans>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值