Spring怎样高效的配置多套数据源

Spring怎样高效的配置多套数据源,第1张

1、首先配置多个datasource

<!-- 主数据库的数据据源 -->

<bean id="masterDataSource" class="orgapachecommonsdbcpBasicDataSource"

destroy-method="close">

<property name="driverClassName" value="oraclejdbcOracleDriver" />

<property name="url" value="jdbc:oracle:thin:@1921681011:1521:trew" />

<property name="username" value="poi" />

<property name="password" value="poi" />

</bean>

<!-- 备份库的数据据源 -->

<bean id="slaveDataSource" class="orgapachecommonsdbcpBasicDataSource"

destroy-method="close">

<property name="driverClassName" value="oraclejdbcOracleDriver" />

<property name="url" value="jdbc:oracle:thin:@1921681012:1521:trew" />

<property name="username" value="poi2" />

<property name="password" value="poi2" />

</bean>

2、写一个DynamicDataSource类继承AbstractRoutingDataSource,并实现determineCurrentLookupKey方法

public class DynamicDataSource extends AbstractRoutingDataSource {

@SuppressWarnings("unused")

private Log logger = LogFactorygetLog(getClass());

@Override

protected Object determineCurrentLookupKey() {

return DbContextHoldergetDbType();

}

}

public class DbContextHolder {

@SuppressWarnings("rawtypes")

private static final ThreadLocal contextHolder = new ThreadLocal();

@SuppressWarnings("unchecked")

public static void setDbType(String dbType) {

contextHolderset(dbType);

}

public static String getDbType() {

return (String) contextHolderget();

}

public static void clearDbType() {

contextHolderremove();

}

}

3 配置动态数据源

<!--将DynamicDataSource Bean加入到Spring的上下文xml配置文件中去,同时配置DynamicDataSource的targetDataSources(多数据源目标)属性的Map映射。-->

<bean id="dataSource" class="cncomcoredatasourceDynamicDataSource">

<property name="targetDataSources">

<map key-type="javalangString">

<entry key="masterDataSource" value-ref="masterDataSource" />

<entry key="slaveDataSource" value-ref="slaveDataSource" />

</map>

</property>

<property name="defaultTargetDataSource" ref="masterDataSource"/>

</bean>

4使用动态数据源(hibernate)

<bean id="sessionFactory"

class="orgspringframeworkormhibernate3LocalSessionFactoryBean">

<property name="dataSource" ref="dataSource" />

<property name="lobHandler" ref="lobHandler"/>

<property name="eventListeners">

<map>

<entry key="post-insert">

<ref bean="logListener"/>

</entry>

<entry key="post-update">

<ref bean="logListener"/>

</entry>

<entry key="post-delete">

<ref bean="logListener"/>

</entry>

</map>

</property>

<property name="hibernateProperties">

<props>

<prop key="hibernatedialect">

orghibernatedialectOracle10gDialect

<!-- orghibernatedialectOracleDerbyDialect -->

</prop>

<prop key="hibernateshow_sql">true</prop>

<!-- <prop key="hibernategenerate_statistics">true</prop> -->

<prop key="hibernateconnectionrelease_mode">

auto

</prop>

<prop key="hibernateautoReconnect">true</prop>

<!--

<prop key="hibernatehbm2ddlauto">update</prop>

-->

<prop key="hibernatecacheuse_second_level_cache">false</prop>

<prop key="hibernatecacheprovider_class">

orghibernatecacheEhCacheProvider

</prop>

<prop key="hibernatecacheuse_query_cache">false</prop>

</props>

</property>

</bean>

使用Hibernate时的事务管理配置示例:

<bean id="transactionManager" class="orgspringframeworkormhibernate3HibernateTransactionManager">

< property name="sessionFactory" ref="sessionFactory" />

bean>

Spring+Hibernate的实质:

就是把Hibernate用到的数据源Datasource,Hibernate的SessionFactory实例,事务管理器HibernateTransactionManager,都交给Spring管理。

那么再没整合之前Hibernate是如何实现事务管理的呢?

通过ServletFilter实现数据库事务的管理,这样就避免了在数据库 *** 作中每次都要进行数据库事务处理。

一事务的4个特性:

原子性:一个事务中所有对数据库的 *** 作是一个不可分割的 *** 作序列,要么全做,要么全部做。

一致性:数据不会因为事务的执行而遭到破坏。

隔离性:一个事务的执行,不受其他事务(进程)的干扰。既并发执行的个事务之间互不干扰。

持久性:一个事务一旦提交,它对数据库的改变将是永久的。

二事务的实现方式:

实现方式共有两种:编码方式;声明式事务管理方式。

基于AOP技术实现的声明式事务管理,实质就是:在方法执行前后进行拦截,然后在目标方法开始之前创建并加入事务,执行完目标方法后根据执行情况提交或回滚事务。

声明式事务管理又有两种方式:基于XML配置文件的方式;另一个是在业务方法上进行@Transactional注解,将事务规则应用到业务逻辑中。

三创建事务的时机:

是否需要创建事务,是由事务传播行为控制的。读数据不需要或只为其指定只读事务,而数据的插入,修改,删除就需要事务管理了。

一种常见的事务管理配置:事务拦截器TransactionInterceptor和事务自动代理BeanNameAutoProxyCreator相结合的方式

<!--定义Hibernate的事务管理器HibernateTransactionManager -->

<bean id="transactionManager"

class="orgspringframeworkormhibernate3HibernateTransactionManager">

<!-- 依赖注入上面定义的sessionFactory -->

<property name="sessionFactory" ref="sessionFactory"/>

</bean>

<!--定义Spring的事务拦截器TransactionInterceptor -->

<bean id="transactionInterceptor" class="orgspringframeworktransactioninterceptorTransactionInterceptor">

<!-- 依赖注入上面定义的事务管理器transactionManager -->

<property name="transactionManager" ref="transactionManager"/>

<!-- 定义需要进行事务拦截的方法及所采用的事务控制类型 -->

<property name="transactionAttributes">

<props>

<!-- 以browse、list、load、get及is开头的所有方法采用只读型事务控制类型 -->

<prop key="browse">PROPAGATION_REQUIRED,readOnly</prop>

<prop key="list">PROPAGATION_REQUIRED,readOnly</prop>

<prop key="load">PROPAGATION_REQUIRED,readOnly</prop>

<prop key="get">PROPAGATION_REQUIRED,readOnly</prop>

<prop key="is">PROPAGATION_REQUIRED,readOnly</prop>

<!-- 所有方法均进行事务控制,如果当前没有事务,则新建一个事务 -->

<prop key="">PROPAGATION_REQUIRED</prop>

</props>

</property>

</bean>

<!-- 定义BeanNameAutoProxyCreatorf进行Spring的事务处理-->

<bean class="orgspringframeworkaopframeworkautoproxyBeanNameAutoProxyCreator">

<!-- 针对指定的bean自动生成业务代理 -->

<property name="beanNames">

<list>

<value>adminService</value>

<value>columnsService</value>

<value>newsService</value>

<value>crawlService</value>

<value>memberLevelService</value>

<value>memberService</value>

<value>categoryService</value>

<value>merService</value>

<value>cartService</value>

<value>ordersService</value>

<value>trafficService</value>

</list>

</property>

<!-- 这个属性为true时,表示被代理的是目标类本身而不是目标类的接口 -->

<property name="proxyTargetClass">

<value>true</value>

</property>

<!-- 依赖注入上面定义的事务拦截器transactionInterceptor -->

<property name="interceptorNames">

<list>

<value>transactionInterceptor</value>

</list>

</property>

</bean>

尤其注意:如下

以上的事务拦截器和事务自动代理方式实现原理:像Struts2一样,都是凭借强大的拦截器功能对业务逻辑方法的调用进行拦截,然后又BeanNameAutoProxyCreator自动生成事务代理,最后送事务管理器,统一管理

Spring+Hibernate的实质:

就是把Hibernate用到的数据源Datasource,Hibernate的SessionFactory实例,事务管理器HibernateTransactionManager,都交给Spring管理。

那么再没整合之前Hibernate是如何实现事务管理的呢?

通过ServletFilter实现数据库事务的管理,这样就避免了在数据库 *** 作中每次都要进行数据库事务处理。

一事务的4个特性:

原子性:一个事务中所有对数据库的 *** 作是一个不可分割的 *** 作序列,要么全做,要么全部做。

一致性:数据不会因为事务的执行而遭到破坏。

隔离性:一个事务的执行,不受其他事务(进程)的干扰。既并发执行的个事务之间互不干扰。

持久性:一个事务一旦提交,它对数据库的改变将是永久的。

二事务的实现方式:

实现方式共有两种:编码方式;声明式事务管理方式。

基于AOP技术实现的声明式事务管理,实质就是:在方法执行前后进行拦截,然后在目标方法开始之前创建并加入事务,执行完目标方法后根据执行情况提交或回滚事务。

声明式事务管理又有两种方式:基于XML配置文件的方式;另一个是在业务方法上进行@Transactional注解,将事务规则应用到业务逻辑中。

三创建事务的时机:

是否需要创建事务,是由事务传播行为控制的。读数据不需要或只为其指定只读事务,而数据的插入,修改,删除就需要事务管理了。

一种常见的事务管理配置:事务拦截器TransactionInterceptor和事务自动代理BeanNameAutoProxyCreator相结合的方式

<!--定义Hibernate的事务管理器HibernateTransactionManager -->

<bean id="transactionManager"

class="orgspringframeworkormhibernate3HibernateTransactionManager">

<!-- 依赖注入上面定义的sessionFactory -->

<property name="sessionFactory" ref="sessionFactory"/>

</bean>

<!--定义Spring的事务拦截器TransactionInterceptor -->

<bean id="transactionInterceptor" class="orgspringframeworktransactioninterceptorTransactionInterceptor">

<!-- 依赖注入上面定义的事务管理器transactionManager -->

<property name="transactionManager" ref="transactionManager"/>

<!-- 定义需要进行事务拦截的方法及所采用的事务控制类型 -->

<property name="transactionAttributes">

<props>

<!-- 以browse、list、load、get及is开头的所有方法采用只读型事务控制类型 -->

<prop key="browse">PROPAGATION_REQUIRED,readOnly</prop>

<prop key="list">PROPAGATION_REQUIRED,readOnly</prop>

<prop key="load">PROPAGATION_REQUIRED,readOnly</prop>

<prop key="get">PROPAGATION_REQUIRED,readOnly</prop>

<prop key="is">PROPAGATION_REQUIRED,readOnly</prop>

<!-- 所有方法均进行事务控制,如果当前没有事务,则新建一个事务 -->

<prop key="">PROPAGATION_REQUIRED</prop>

</props>

</property>

</bean>

<!-- 定义BeanNameAutoProxyCreatorf进行Spring的事务处理-->

<bean class="orgspringframeworkaopframeworkautoproxyBeanNameAutoProxyCreator">

<!-- 针对指定的bean自动生成业务代理 -->

<property name="beanNames">

<list>

<value>adminService</value>

<value>columnsService</value>

<value>newsService</value>

<value>crawlService</value>

<value>memberLevelService</value>

<value>memberService</value>

<value>categoryService</value>

<value>merService</value>

<value>cartService</value>

<value>ordersService</value>

<value>trafficService</value>

</list>

</property>

<!-- 这个属性为true时,表示被代理的是目标类本身而不是目标类的接口 -->

<property name="proxyTargetClass">

<value>true</value>

</property>

<!-- 依赖注入上面定义的事务拦截器transactionInterceptor -->

<property name="interceptorNames">

<list>

<value>transactionInterceptor</value>

</list>

</property>

</bean>

尤其注意:如下

以上的事务拦截器和事务自动代理方式实现原理:像Struts2一样,都是凭借强大的拦截器功能对业务逻辑方法的调用进行拦截,然后又BeanNameAutoProxyCreator自动生成事务代理,最后送事务管理器,统一管理

我提供一个实例:

数据库是MYSQL , 数据源是C3P0 ,

-----------

1) 建表语句 :

----------------

DROP TABLE IF EXISTS book ;

CREATE TABLE book(

id int(11) NOT NULL auto_increment COMMENT 'primary key',

name varchar(60) default NULL COMMENT 'book name',

PRIMARY KEY (`id`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='my book table';

----------------

注意了,在MYSql 中 表的引擎一定要用InnoDB ,如果用MyISAM 的话,是不支持事务的。

2) JAVA Bean

Bookjava

-------------------

package comspringdemobean;

import javaioSerializable;

public class Book implements Serializable {

public Book(){}

public Book(String name){

thisname = name;

}

/

ID

/

private Integer id ;

/

书名

/

private String name ;

// getter and setter

public Integer getId() {

return id;

}

public void setId(Integer id) {

thisid = id;

}

public String getName() {

return name;

}

public void setName(String name) {

thisname = name;

}

}

-------------------

3)Bookxml 配置

---------------------

<xml version="10" encoding="UTF-8" >

<!DOCTYPE sqlMap PUBLIC "-//ibatisapacheorg//DTD SQL Map 20//EN"

"">

<sqlMap namespace="Book" >

<typeAlias alias="book" type="comspringdemobeanBook"/>

<resultMap id="result_map_book" class="book" >

<result property="id" column="id" javaType="integer"/>

<result property="name" column="name" javaType="string"/>

</resultMap>

<insert id="insertBook" parameterClass="book">

insert book(name) values(#name#)

</insert>

<update id="updateBook" parameterClass="book">

update book set name=#name# where id=#id#

</update>

<delete id="deleteBook" parameterClass="int">

delete from book where id=#value#

</delete>

<select id="selectBookById" parameterClass="int" resultMap="result_map_book">

select id , name from book where id=#value#

</select>

<select id="selectBookByName" parameterClass="string" resultMap="result_map_book">

select id , name from book where name like #value#

</select>

</sqlMap>

---------------------

4)spring 的 applicationContextxml

---------------

<xml version="10" encoding="UTF-8">

<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 20//EN" "">

<beans>

<!-- 引入参数配置文件 -->

<bean id="propertyConfigurer" class="orgspringframeworkbeansfactoryconfigPropertyPlaceholderConfigurer">

<property name="locations">

<list>

<value>jdbcproperties</value>

</list>

</property>

</bean>

<!-- 配置数据源 -->

<bean id="dataSource" class="commchangev2c3p0ComboPooledDataSource">

<property name="driverClass"><value>$</value></property>

<property name="jdbcUrl"><value>$</value></property>

<property name="user"><value>$</value></property>

<property name="password"><value>$</value></property>

<property name="initialPoolSize"><value>$</value></property>

<property name="minPoolSize"><value>$</value></property>

<property name="maxPoolSize"><value>$</value></property>

</bean>

<!-- 事务管理器 -->

<bean id="transactionManager" class="orgspringframeworkjdbcdatasourceDataSourceTransactionManager">

<property name="dataSource">

<ref local="dataSource"/>

</property>

</bean>

<!-- 事务代理拦截器的配置 -->

<bean id="baseTransactionProxy" abstract="true" class="orgspringframeworktransactioninterceptorTransactionProxyFactoryBean">

<property name="transactionManager">

<ref bean="transactionManager" />

</property>

<property name="transactionAttributes">

<props>

<prop key="insert">PROPAGATION_REQUIRED</prop>

<prop key="update">PROPAGATION_REQUIRED</prop>

<prop key="delete">PROPAGATION_REQUIRED</prop>

<prop key="">PROPAGATION_REQUIRED,readOnly</prop>

</props>

</property>

</bean>

<!-- ibatis sqlMapClient 配置 -->

<bean id="sqlMapClient" class="orgspringframeworkormibatisSqlMapClientFactoryBean">

<property name="configLocation">

<value>classpath:sqlMapConfigxml</value>

</property>

<property name="dataSource">

<ref bean="dataSource"/>

</property>

</bean>

<!-- dao配置 -->

<bean id="ibatis_BookDao" class="comspringdemodaoIbatis_BookDao">

<property name="sqlMapClient" >

<ref bean="sqlMapClient"/>

</property>

</bean>

<!-- 添加了事务的管理类 -->

<bean id="ibatis_BookManager" parent="baseTransactionProxy">

<property name="target">

<bean class="comspringdemomanagerIbatis_BookManager">

<property name="dao">

<ref bean="ibatis_BookDao"/>

</property>

</bean>

</property>

</bean>

</beans>

---------------

5) 数据源参数配置文件:jdbcproperties

------------

jdbcdriverClass=commysqljdbcDriver

jdbcurl=jdbc:mysql://localhost:3306/springdemouseUnicode=true&characterEncoding=utf-8

jdbcuser=root

jdbcpassword=root

jdbcinitialPoolSize=1

jdbcminPoolSize=1

jdbcmaxPoolSize=10

------------

6) IBATIS 的初始化配置 sqlMapConfigxml

------------

<xml version="10" encoding="UTF-8" >

<!DOCTYPE sqlMapConfig

PUBLIC "-//ibatisapacheorg//DTD SQL Map Config 20//EN"

"">

<sqlMapConfig>

<settings useStatementNamespaces="true" />

<sqlMap resource="com/spring/demo/bean/Bookxml"/>

</sqlMapConfig>

------------

配置完毕,下面是DAO 和 测试方法:

Ibatis_BookDaojava

----------------

package comspringdemodao;

import javautilList;

import orgspringframeworkormibatissupportSqlMapClientDaoSupport;

import comspringdemobeanBook;

public class Ibatis_BookDao extends SqlMapClientDaoSupport {

/

添加一本书

@param book

/

public void insertBook(Book book){

thisgetSqlMapClientTemplate()insert("BookinsertBook", book);

}

/

修改一本书

@param book

/

public void updateBook(Book book){

thisgetSqlMapClientTemplate()update("BookupdateBook", book);

}

/

根据ID来删除一本书

@param id

/

public void deleteBook(Integer id){

thisgetSqlMapClientTemplate()delete("BookdeleteBook", id);

}

/

根据ID来查询书对象

@param id

@return

/

public Book selectBookById(Integer id){

return (Book)thisgetSqlMapClientTemplate()queryForObject("BookselectBookById", id);

}

/

根据书名来查询相关书记录列表

@param name

@return

/

public List selectBookByName(String name){

return thisgetSqlMapClientTemplate()queryForList("BookselectBookByName", "%"+name+"%" );

}

}

----------------

Ibatis_BookManagerjava

-------------------

package comspringdemomanager;

import javautilList;

import comspringdemobeanBook;

import comspringdemodaoIbatis_BookDao;

public class Ibatis_BookManager {

private Ibatis_BookDao dao = null ;

/

批量添加书本,如果列表长度超过3,就抛出异常

@param books

/

public void insertBooks(List books){

for(int i=0 ; i<bookssize() ;i++){

if(i>2){

Systemoutprintln("列表太长,中断事务");

throw new RuntimeException("中断事务异常,当列表长度大于3的时候故意抛出,看看事务是否回滚");

}

Book book = (Book)booksget(i);

daoinsertBook(book);

}

}

/

添加一本书

@param book

/

public void insertBook(Book book){

thisdaoinsertBook(book);

}

/

修改一本书

@param book

/

public void updateBook(Book book){

thisdaoupdateBook(book);

}

/

根据ID来删除一本书

@param id

/

public void deleteBook(Integer id){

thisdaodeleteBook(id);

}

/

根据ID来查询书对象

@param id

@return

/

public Book selectBookById(Integer id){

return thisdaoselectBookById(id);

}

/

根据书名来查询相关书记录列表

@param name

@return

/

public List selectBookByName(String name){

return thisdaoselectBookByName(name);

}

// getter and setter //

public Ibatis_BookDao getDao() {

return dao;

}

public void setDao(Ibatis_BookDao dao) {

thisdao = dao;

}

-------------------

测试类:

IbatisDemojava

------------------

package comspringdemo;

import javautilArrayList;

import javautilList;

import orgspringframeworkcontextApplicationContext;

import orgspringframeworkcontextsupportClassPathXmlApplicationContext;

import comspringdemobeanBook;

import comspringdemomanagerIbatis_BookManager;

import comspringdemomanagerJdbc_BookManager;

public class IbatisDemo {

/

@param args

/

public static void main(String[] args) {

ApplicationContext context = new ClassPathXmlApplicationContext("applicationContextxml") ;

Ibatis_BookManager manager = (Ibatis_BookManager)contextgetBean("ibatis_BookManager");

List books = new ArrayList();

booksadd(new Book("book_10"));

booksadd(new Book("book_11"));

booksadd(new Book("book_12"));

booksadd(new Book("book_13"));

managerinsertBooks(books);

Systemoutprintln("OK");

}

}

------------------

说明:MYSQL 的事务完整性我是测试过的。

之前有个朋友吧数据库换成 SQL SERVER 的时候事务完整性就出现问题。

这个问题有待研究。

这篇文章主要探讨怎么用Spring来装配组件及其事务管理 在J EE工程里连接到一个简单的数据库并不是什么难题 但是如果要综合组装企业类的组件就变得复杂了 一个简单的组件有一个或多个数据库支撑 所以 我们说到整合两个或多个的组件时 我们希望能够维持跨组件的许多数据库的运作的原子性 J EE提供了这些组件的容器 可以保证处理的原子性和独立性 在没有J EE的情况下我们可以用Spring Spring基于IoC模式(即反转模式) 不仅可以配置组件服务 还可以配置相应的方法 为了更好的实现本文的目的 我们使用Hibernate来做相应的后台开发 装配组件事务 假设在组件库里 我们已经有一个审核组件(audit ponent) 里面有可以被客户端调用的方法 接着 当我们想要构建一个处理订单的体系 我们发现设计需要的OrderListManager组件服务同样需要审核组件服务 OrderListManager创建和管理订单 每一个服务都含有自己的事务属性 当这时调用审核组件 就可以把OrderListManager的处理内容传给它 也许将来新的业务服务(business service)同样需要审核组件 那这时它调用的事务内容已经不一样了 在网络上的结果就是 虽然审核的功能保持不变 但是可以和别的事件功能组合在一起 用这些方法属性来提供不同的运行时的处理参数 在图 中有两个分开的调用流程 在流程 里 如果客户端含有一个TX内容 OrderListManager 要由一个新的TX开始或者参与其中 取决于客户端在不在TX里以及OrderListManager方法指定的TX属性 这在它调用AuditManager方法的时候仍然适用 图 装配组件事务 EJB体系通过装配者声明正确的事务属性来获得这种适应性 我们不是在探讨是否声明事务管理 因为这会使运行时的事务参数代码发生改变 几乎所有的J EE工程提供了分布的事务管理来配合提交协议例如X/Open XA specification 现在的问题是我们能不能不用EJB来获得相同的功能?Spring是其中一种解决方案 来看一下Spring如何处理这样的问题 用Spring来管理事务 我们将看到的是一个轻量级的事务机制 实际上 它可以管理组件层的事务集成 Spring就是如此 它的优点是我们可以不用捆绑在J EE的服务例如JNDI数据库 最棒的是如果我们想把这个事务机制与已经存在的J EE框架组合在一起 没有任何问题 就好像我们找到了杠杆中完美的支撑点一样 Spring的另一个机制是使用了AOP框架 这个框架使用了一个可以使用AOP的Spring bean factory 在Spring特定的配置文件applicationContext xml里通过特定的组件层的事件来指定 <beans><! other code goes here ><bean id= orderListManager class= springframework transaction  interceptor TransactionProxyFactoryBean ><property name= transactionManager ><ref local= transactionManager /></property><property name= target ><ref local= orderListManagerTarget /></property><property name= transactionAttributes ><props><prop key= getAllOrderList >PROPAGATION_REQUIRED</prop><prop key= getOrderList >PROPAGATION_REQUIRED</prop><prop key= createOrderList >PROPAGATION_REQUIRED</prop><prop key= addLineItem >  PROPAGATION_REQUIRED example exception FacadeException</prop><prop key= getAllLineItems >PROPAGATION_REQUIRED readOnly</prop><prop key= queryNumberOfLineItems >PROPAGATION_REQUIRED readOnly</prop></props></property></bean></beans>一旦我们在服务层指定了事务属性 它们就被一个继承 springframework transaction PlatformTransactionManager 接口的类截获 这个接口如下:public interface PlatformTransactionManager{TransactionStatus getTransaction(TransactionDefinition definition);void mit(TransactionStatus status);void rollback(TransactionStatus status);} Hibernate事务管理 一旦我们决定了使用Hibernate作为ORM工具 我们下一步要做的就是用Hibernate特定的事务管理实例来配置 <beans><! other code goes here ><bean id= transactionManager class= springframework orm hibernate HibernateTransactionManager ><property name= sessionFactory ><ref local= sessionFactory /></property></bean></beans>我们来看看什么是 装配组件事务 你也许注意到了那个OrderListManager 特有的TX属性 那个服务层的组件 我们的工程的主要的东西在表 的BDOM里: educity cn/img_ / / / gif > 图 业务领域对象模型 (BDOM) 为了用实例说明 我们来列出工程里的非功能需求(NFR) 事务在数据库appfuse 里保存 审核时要登入到另一个数据库appfuse 里 出于安全的考虑 数据库有防火墙保护 事务组件可以重用 所有访问事件必须经过在事务服务层的审核 出于以上的考虑 我们决定了OrderListManager 服务将委托任何审核记录来调用已有的AuditManager 组件 这产生了表 这样更细致的结构educity cn/img_ / / / gif > 图 组件服务结构设计 值得注意的是 由于我们的NFR 我们要映射OrderListManager相关的事物到appfuse 数据库里去 而审核相关的到appfuse 这样 任何审核的时候 OrderListManager 组件都会调用AuditManager 组件 我们认为OrderListManager 组件里的所有方法都要执行 因为我们通过服务来创建次序和具体项目 那么AuditManager 组件里的服务呢 因为它做的是审核的动作 我们关心的是为系统里所有的事务记录审核情况 这样的需求是 即使事务事件失败了 我们也要记录登录的审核情况 AuditManager 组件同样要有自己的事件 因为它同样与自己的数据库有关联 如下所示 <beans><!—其他代码在这里 ><bean id= auditManager class= springframework transactioninterceptor TransactionProxyFactoryBean ><property name= transactionManager ><ref local= transactionManager /></property><property name= target ><ref local= auditManagerTarget /></property><property name= transactionAttributes ><props><prop key= log >PROPAGATION_REQUIRES_NEW</prop></props></property></bean></beans>我们现在把注意力放到这两个事务createOrderList 和 addLineItem中来 作为我们的试验 同时注意我们并没有要求最好的设计——你可能注意到了 addLineItem 方法抛出了 FacadeException 而 createOrderList 没有 在产品设计中 你也许希望每一个方法都处理异常 public class OrderListManagerImplimplements OrderListManager{private AuditManager auditManager;public Long createOrderList (OrderList orderList){Long orderId = orderListDAO createOrderList(orderList);auditManager log(new AuditObject(ORDER + orderId CREATE));return orderId;}public void addLineItem (Long orderId LineItem lineItem)throws FacadeException{Long lineItemId = orderListDAO addLineItem(orderId lineItem);auditManager log(new AuditObject(LINE_ITEM + lineItemId CREATE));int numberOfLineItems = orderListDAO queryNumberOfLineItems(orderId);if(numberOfLineItems > ){log( Added LineItem + lineItemId + to Order + orderId + ;But rolling back ! );throw new FacadeException( Make a newOrder for this line item );}else{log( Added LineItem + lineItemId + to Order + orderId + );}}//其他代码在这里}要创建一个这个试验的异常 我们已经介绍了其他事务规则规定一个特定的次序不能在同一行里包含两个项目 我们应该注意到createOrderList 和 addLineItem调用了auditManager log() 方法 你应该也注意到了上面方法中的事务属性 <bean id= orderListManager class= springframework transaction interceptor TransactionProxyFactoryBean ><pro lishixinzhi/Article/program/Java/ky/201311/28501

<bean id="sessionFactory

class="orgspringframeworkormhibernate3annotationAnnotationSessionFactoryBean"

<property name="dataSource" ref="oracleDataSource"/>

<property name="hibernateProperties">

<props>

<prop key="hibernatedialect">

${hibernatedialect}

</prop>

<prop key="hibernateconnectionrelease_mode">

after_transaction

</prop>

<prop key="hibernateshow_sql">true</prop>

<prop key="hibernatehbm2ddlauto">${hibernatehbm2ddlauto}</prop>

<prop key="hibernatetempuse_jdbc_metadata_defaults">false</prop>

</props>

</property>

<!-- Must references all OR mapping files -->

<property name="defineMappingResources">

<list>

<value>classpath:-qlxml</value>

</list>

</property>

</bean>

Struts:

1Struts框架结构 如右图:

Struts对Model,View和Controller都提供了对应的组件。

在右图中,ActionServlet,这个类是Struts的核心控制器,负责拦截来自用户的请求。

Action,这个类通常由用户提供,该控制器负责接收来自ActionServlet的请求,并根据该请求调用模型的业务逻辑方法处理请求,并将处理结果返回给JSP页面显示。

2Model部分 由ActionForm和JavaBean组成,其中ActionForm用于封装用户的请求参数,封装成ActionForm对象,该对象被ActionServlet转发给Action,Action根据ActionForm里面的请求参数处理用户的请求。

JavaBean则封装了底层的业务逻辑,包括数据库访问等。

3View部分 该部分采用JSP实现。

Struts提供了丰富的标签库,通过标签库可以减少脚本的使用,自定义的标签库可以实现与Model的有效交互,并增加了现实功能。对应上图的JSP部分。

4Controller组件 Controller组件有两个部分组成——系统核心控制器,业务逻辑控制器。

系统核心控制器,对应上图的ActionServlet。该控制器由Struts框架提供,继承>

业务逻辑控制器,负责处理用户请求,本身不具备处理能力,而是调用Model来完成处理。对应Action部分。

如果是WEB项目可以把包放在项目下WEB-INF/lib目录下若是J2SE或J2ME项目则放在与src同级的lib目录下学习深入后也可自己定义包的存放目录至于spring框架的用法是要看项目与团队的编程习惯而定只要不错怎么用都行 以下我就给个Spring的实例:

xml version="10" encoding="UTF-8"

beans xmlns= ;

xmlns:xsi= ;

xmlns:aop= ;

xmlns:tx= ;

xsi:schemaLocation=

;

default-autowire="byName" default-lazy-init="true"

bean id="dataSource"

class="orgapachecommonsdbcpBasicDataSource"

property name="driverClassName"

value$/value

/property

property name="url"

value$/value

/property

property name="username"

value$/value

/property

property name="password"

value$/value

/property

/bean

bean id="sessionFactory"

class="orgspringframeworkormhibernate3LocalSessionFactoryBean"

property name="dataSource" ref="dataSource" /

property name="mappingDirectoryLocations"

list

valueclasspath:/com/wxc/entity/model/value

/list

/property

property name="schemaUpdate" value="true" /

property name="hibernateProperties"

props

prop key="hibernatedialect"

$

/prop

prop key="hibernateconnectionpool_size"5/prop

prop key="hibernateshow_sql"true/prop

prop key="hibernatecglibuse_reflection_optimizer"

true

/prop

prop key="hibernatecacheprovider_class"

orghibernatecacheEhCacheProvider

/prop

prop key="hibernatehibernatecacheuse_query_cache"

true

/prop

/props

/property

/bean

bean id="hibernateInterceptor" class="orgspringframeworkormhibernate3HibernateInterceptor"

property name="sessionFactory"

ref bean="sessionFactory" /

/property

/bean

!-- setup transaction manager--

bean id="transactionManager" class="orgspringframeworkormhibernate3HibernateTransactionManager"

property name="sessionFactory"

ref bean="sessionFactory" /

/property

/bean

bean name="publicManager" class="comwxcmanagerPublicManager"/

!-- 支持 @AspectJ 标记--

aop:aspectj-autoproxy /

!-- 以AspectJ方式 定义 AOP --

aop:config proxy-target-class="true"

aop:advisor pointcut="execution( comwxcdaoDao())" advice-ref="txAdvice" /

aop:advisor pointcut="execution( comwxcmanagerManager())" advice-ref="txAdvice" /

!--

--

/aop:config

!-- 基本事务定义,使用transactionManager作事务管理,默认get方法的事务为readonly,其余方法按默认设置

默认的设置请参考Spring文档事务一章 --

tx:advice id="txAdvice"

tx:attributes

tx:method name="get" read-only="true" /

tx:method name="find" read-only="true" /

tx:method name="count" read-only="true" /

tx:method name="remove" read-only="true" /

tx:method name="" rollback-for="RuntimeException" /

/tx:attributes

/tx:advice

/beans

以上就是关于Spring怎样高效的配置多套数据源全部的内容,包括:Spring怎样高效的配置多套数据源、spring的事务管理有几种方式实现,如何实现、spring管理jdbc事务的Demo代码等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/web/9566648.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-04-29
下一篇2023-04-29

发表评论

登录后才能评论

评论列表(0条)

    保存