您的位置:首页 > 编程语言 > Java开发

Spring_ibatis_jta多数据源配置

2016-04-12 11:22 363 查看
Spring+iBatis+JOTM实现JTA事务

JOTM是个开源的JTA事务管理组件,可以让程序脱离J2EE容器而获得分布式事务管理的能力。

测试过程如下:

一、环境

1、准备软件环境

spring-framework-2.5.6.SEC01-with-dependencies.zip

ibatis-2.3.4

ow2-jotm-dist-2.1.4-bin.tar.gz

MySQL-5.1

JDK1.5

2、创建数据库环境,注意数据库引擎为InnoDB,只有这样才能支持事务。

CREATE DATABASE IF NOT EXISTS testdb_a DEFAULT CHARACTER SET utf8;

USE testdb_a;

DROP TABLE IF EXISTS tab_a;

CREATE TABLE tab_a (

id bigint(20) NOT NULL,

name varchar(60) DEFAULT NULL,

address varchar(120) DEFAULT NULL,

PRIMARY KEY (id)

) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE DATABASE IF NOT EXISTS testdb_b DEFAULT CHARACTER SET utf8;

USE testdb_b;

DROP TABLE IF EXISTS tab_b;

CREATE TABLE tab_b (

id bigint(20) NOT NULL,

name varchar(60) DEFAULT NULL,

address varchar(120) DEFAULT NULL,

PRIMARY KEY (id)

) ENGINE=InnoDB DEFAULT CHARSET=utf8;

二、建立项目testJOTM

1、建立项目后,准备依赖的类库,结构如下:

│ spring-aop.jar

│ spring-beans.jar

│ spring-context-support.jar

│ spring-context.jar

│ spring-core.jar

│ spring-jdbc.jar

│ spring-jms.jar

│ spring-orm.jar

│ spring-test.jar

│ spring-tx.jar

│ spring-web.jar

│ spring-webmvc-portlet.jar

│ spring-webmvc-struts.jar

│ spring-webmvc.jar

│ aspectjrt.jar

│ aspectjweaver.jar

│ cglib-nodep-2.1_3.jar

│ asm-2.2.3.jar

│ log4j-1.2.15.jar

│ asm-commons-2.2.3.jar

│ asm-util-2.2.3.jar

│ aopalliance.jar

│ mysql-connector-java-5.1.6-bin.jar



├─ibatis

│ ibatis-2.3.4.726.jar

│ sql-map-2.dtd

│ sql-map-config-2.dtd



├─jotm

│ license.txt

│ xapool.jar

│ jotm-core.jar

│ jotm-standalone.jar

│ jotm-jms.jar

│ jotm-datasource.jar

│ ow2-jta-1.1-spec.jar

│ jotm-client.jar



├─jakarta-commons

│ commons-attributes-api.jar

│ commons-attributes-compiler.jar

│ commons-beanutils.jar

│ commons-codec.jar

│ commons-collections.jar

│ commons-dbcp.jar

│ commons-digester.jar

│ commons-discovery.jar

│ commons-fileupload.jar

│ commons-httpclient.jar

│ commons-io.jar

│ commons-lang.jar

│ commons-logging.jar

│ commons-pool.jar

│ commons-validator.jar



├─junit

│ junit-3.8.2.jar

│ junit-4.4.jar

│ license.txt



└─log4j

log4j-1.2.15.jar

2、根据表建立entity和SQLMap

public class TabA implements Serializable {

private Long id;

private String name;

private String address;

//省略getter/setter

public class TabB implements Serializable {

private Long id;

private String name;

private String address;

//省略getter/setter

TabA.xml

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

<!DOCTYPE sqlMap PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN" "http://ibatis.apache.org/dtd/sql-map-2.dtd" >

<!-- 表名:tab_a -->

<sqlMap namespace="tab_a">

<typeAlias alias="TabA" type="com.lavasoft.stu.jtom.entity.TabA"/>

<resultMap id="result_base" class="TabA">

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

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

<result property="address" column="address"/>

</resultMap>

<!-- 添加 -->

<insert id="insert" parameterClass="TabA">

insert into tab_a(

id,

name,

address

) values (

#id#,

#name#,

#address#

)

<selectKey keyProperty="id" resultClass="long">

select LAST_INSERT_ID()

</selectKey>

</insert>

<!-- 更新 -->

<update id="update" parameterClass="TabA">

update tab_a set

id = #id#,

name = #name#,

address = #address#

where id = #id#

</update>

<!-- 删除 -->

<delete id="deleteById" parameterClass="long">

delete from tab_a

where id = #value#

</delete>

<!-- 根据ID获取 -->

<select id="findById" parameterClass="long" resultMap="tab_a.result_base">

select *

from tab_a

where id = #value#

</select>

</sqlMap>

TabB.xml

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

<!DOCTYPE sqlMap PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN" "http://ibatis.apache.org/dtd/sql-map-2.dtd" >

<!-- 表名:tab_b -->

<sqlMap namespace="tab_b">

<typeAlias alias="TabB" type="com.lavasoft.stu.jtom.entity.TabB"/>

<resultMap id="result_base" class="TabB">

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

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

<result property="address" column="address"/>

</resultMap>

<!-- 添加 -->

<insert id="insert" parameterClass="TabB">

insert into tab_b(

id,

name,

address

) values (

#id#,

#name#,

#address#

)

<selectKey keyProperty="id" resultClass="long">

select LAST_INSERT_ID()

</selectKey>

</insert>

<!-- 更新 -->

<update id="update" parameterClass="TabB">

update tab_b set

id = #id#,

name = #name#,

address = #address#

where id = #id#

</update>

<!-- 删除 -->

<delete id="deleteById" parameterClass="long">

delete from tab_b

where id = #value#

</delete>

<!-- 根据ID获取 -->

<select id="findById" parameterClass="long" resultMap="tab_b.result_base">

select *

from tab_b

where id = #value#

</select>

</sqlMap>

/**

* TabADAO

*

* @author leizhimin 2009-6-25 12:39:19

*/

public interface TabADAO {

/**

* 保存一个TabA对象

*

* @param tabA TabA对象

* @return 返回保存后的对象

*/

TabA saveTabA(TabA tabA);

/**

* 更新一个TabA

*

* @param tabA TabA对象

* @return 返回更新后的对象

*/

TabA updateTabA(TabA tabA);

/**

* 删除指定标识的一个TabA

*

* @param id TabA标识

*/

void deleteTabAById(Long id);

/**

* 获取指定标识的TabA

*

* @param id TabA标识

* @return 所查询到的TabA

*/

TabA findTabAById(Long id);

}

/**

* TabADAO

*

* @author leizhimin 2009-6-25 12:43:55

*/

public class TabADAOImpl extends SqlMapClientDaoSupport implements TabADAO {

/**

* 保存一个TabA对象

*

* @param tabA TabA对象

* @return 返回保存后的对象

*/

public TabA saveTabA(TabA tabA) {

Long id = (Long) getSqlMapClientTemplate().insert("tab_a.insert", tabA);

tabA.setId(id);

return tabA;

}

/**

* 更新一个TabA

*

* @param tabA TabA对象

* @return 返回更新后的对象

*/

public TabA updateTabA(TabA tabA) {

getSqlMapClientTemplate().update("tab_a.update", tabA);

return tabA;

}

/**

* 删除指定标识的一个TabA

*

* @param id TabA标识

*/

public void deleteTabAById(Long id) {

getSqlMapClientTemplate().delete("tab_a.deleteById",id);

}

/**

* 获取指定标识的TabA

*

* @param id TabA标识

* @return 所查询到的TabA

*/

public TabA findTabAById(Long id) {

return (TabA) getSqlMapClientTemplate().queryForObject("tab_a.findById",id);

}

}

B的DAO和A类似,就不写了。

/**

* 测试JOTM的Service

*

* @author leizhimin 2009-6-25 12:53:55

*/

public interface StuJotmService {

/**

* 同时保存TabA、TabB

*

* @param a TabA对象

* @param b TabB对象

*/

void saveAB(TabA a, TabB b);

/**

* 同时更新TabA、TabB

*

* @param a TabA对象

* @param b TabB对象

*/

void updateAB(TabA a, TabB b);

/**

* 删除指定id的TabA、TabB记录

*

* @param id 指定id

*/

void deleteABif(Long id);

}

/**

* Created by IntelliJ IDEA.

*

* @author leizhimin 2009-6-25 12:58:48

*/

//@Transactional

public class StuJotmServiceImpl implements StuJotmService {

private TabADAO tabADAO;

private TabBDAO tabBDAO;

/**

* 同时保存TabA、TabB

*

* @param a TabA对象

* @param b TabB对象

*/

// @Transactional(readOnly=false)

public void saveAB(TabA a, TabB b) {

tabADAO.saveTabA(a);

tabBDAO.saveTabB(b);

}

/**

* 同时更新TabA、TabB

*

* @param a TabA对象

* @param b TabB对象

*/

// @Transactional(readOnly=false)

public void updateAB(TabA a, TabB b) {

tabADAO.updateTabA(a);

tabBDAO.updateTabB(b);

}

/**

* 删除指定id的TabA、TabB记录

*

* @param id 指定id

*/

// @Transactional(readOnly=false)

public void deleteABif(Long id) {

tabADAO.deleteTabAById(id);

tabBDAO.deleteTabBById(id);

}

public void setTabADAO(TabADAO tabADAO) {

this.tabADAO = tabADAO;

}

public void setTabBDAO(TabBDAO tabBDAO) {

this.tabBDAO = tabBDAO;

}

}

/**

* Spring上下文工具

*

* @author leizhimin 2008-8-13 14:42:58

*/

public class ApplicationContextUtil {

private static ApplicationContext applicationContext;

static {

if (applicationContext == null)

applicationContext = rebuildApplicationContext();

}

/**

* 重新构建Spring应用上下文环境

*

* @return ApplicationContext

*/

public static ApplicationContext rebuildApplicationContext() {

return new ClassPathXmlApplicationContext("/ApplicationContext.xml");

}

/**

* 获取Spring应用上下文环境

*

* @return

*/

public static ApplicationContext getApplicationContext() {

return applicationContext;

}

/**

* 简单的上下文环境测试

*/

public static void main(String[] args) {

rebuildApplicationContext();

if (applicationContext == null) {

System.out.println("ApplicationContext is null");

} else {

System.out.println("ApplicationContext is not null!");

}

}

}

三、做JTOM、Spring、iBatis、Log4j等配置

JOTM配置:carol.properties

#JNDI调用协议

carol.protocols=jrmp

#不使用CAROL JNDI封装器

carol.start.jndi=false

#不启动命名服务器

carol.start.ns=false

Spring配置:ApplicationContext.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:jee="http://www.springframework.org/schema/jee"

xmlns:aop="http://www.springframework.org/schema/aop"

xmlns:tx="http://www.springframework.org/schema/tx"

xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-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">

<!--指定Spring配置中用到的属性文件-->

<bean id="propertyConfig"

class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">

<property name="locations">

<list>

<value>classpath:jdbc.properties</value>

</list>

</property>

</bean>

<!-- JOTM实例 -->

<bean id="jotm" class="org.springframework.transaction.jta.JotmFactoryBean"/>

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

<bean id="myJtaManager"

class="org.springframework.transaction.jta.JtaTransactionManager">

<property name="userTransaction">

<ref local="jotm"/>

</property>

</bean>

<!-- 数据源A -->

<bean id="dataSourceA" 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="${jdbc.driver}"/>

<property name="url" value="${jdbc.url}"/>

</bean>

</property>

<property name="user" value="${jdbc.username}"/>

<property name="password" value="${jdbc.password}"/>

</bean>

<!-- 数据源B -->

<bean id="dataSourceB" 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="${jdbc2.driver}"/>

<property name="url" value="${jdbc2.url}"/>

</bean>

</property>

<property name="user" value="${jdbc2.username}"/>

<property name="password" value="${jdbc.password}"/>

</bean>

<!-- 事务切面配置 -->

<aop:config>

<aop:pointcut id="serviceOperation"

expression="execution(* *..servi1ce*..*(..))"/>

<aop:advisor pointcut-ref="serviceOperation"

advice-ref="txAdvice"/>

</aop:config>

<!-- 通知配置 -->

<tx:advice id="txAdvice" transaction-manager="myJtaManager">

<tx:attributes>

<tx:method name="delete*" rollback-for="Exception"/>

<tx:method name="save*" rollback-for="Exception"/>

<tx:method name="update*" rollback-for="Exception"/>

<tx:method name="*" read-only="true" rollback-for="Exception"/>

</tx:attributes>

</tx:advice>

<!--根据dataSourceA和sql-map-config_A.xml创建一个SqlMapClientA-->

<bean id="sqlMapClientA"

class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">

<property name="dataSource">

<ref local="dataSourceA"/>

</property>

<property name="configLocation">

<value>sql-map-config_A.xml</value>

</property>

</bean>

<!--根据dataSourceB和sql-map-config_B.xml创建一个SqlMapClientB-->

<bean id="sqlMapClientB"

class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">

<property name="dataSource">

<ref local="dataSourceB"/>

</property>

<property name="configLocation">

<value>sql-map-config_B.xml</value>

</property>

</bean>

<!--根据sqlMapClientA创建一个SqlMapClientTemplate的模版类实例sqlMapClientTemplateA-->

<bean id="sqlMapClientTemplateA"

class="org.springframework.orm.ibatis.SqlMapClientTemplate">

<property name="sqlMapClient" ref="sqlMapClientA"/>

</bean>

<!--根据sqlMapClientB创建一个SqlMapClientTemplate的模版类实例sqlMapClientTemplateB-->

<bean id="sqlMapClientTemplateB"

class="org.springframework.orm.ibatis.SqlMapClientTemplate">

<property name="sqlMapClient" ref="sqlMapClientB"/>

</bean>

<!-- 配置DAO,并注入所使用的sqlMapClientTemplate实例 -->

<bean id="tabADAO" class="com.lavasoft.stu.jtom.dao.impl.TabADAOImpl">

<property name="sqlMapClientTemplate" ref="sqlMapClientTemplateA"/>

</bean>

<bean id="tabBDAO" class="com.lavasoft.stu.jtom.dao.impl.TabBDAOImpl">

<property name="sqlMapClientTemplate" ref="sqlMapClientTemplateB"/>

</bean>

<!-- Service配置,注入DAO -->

<bean id="stuJotmService" class="com.lavasoft.stu.jtom.service.StuJotmServiceImpl">

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

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

</bean>

</beans>

数据库配置:jdbc.properties

jdbc.database=cms_release

jdbc.driver=com.mysql.jdbc.Driver

jdbc.url=jdbc:mysql://192.168.0.2:3306/testdb_a?useUnicode=true&characterEncoding=utf8&autoReconnect=true&zeroDateTimeBehavior=convertToNull

jdbc.username=root

jdbc.password=leizhimin

jdbc2.database=cms_release

jdbc2.driver=com.mysql.jdbc.Driver

jdbc2.url=jdbc:mysql://192.168.0.1:3306/testdb_b?useUnicode=true&characterEncoding=utf8&autoReconnect=true&zeroDateTimeBehavior=convertToNull

jdbc2.username=root

jdbc2.password=leizhimin

iBatis的SQLMap配置:

sql-map-config_A.xml

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

<!DOCTYPE sqlMapConfig

PUBLIC "-//ibatis.apache.org//DTD SQL Map Config 2.0//EN"

"http://ibatis.apache.org/dtd/sql-map-config-2.dtd">

<sqlMapConfig>

<settings cacheModelsEnabled="true" enhancementEnabled="true"

lazyLoadingEnabled="true" errorTracingEnabled="true"

useStatementNamespaces="true"/>

<sqlMap resource="com/lavasoft/stu/jtom/entity/sqlmap/TabA.xml"/>

</sqlMapConfig>

sql-map-config_B.xml

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

<!DOCTYPE sqlMapConfig

PUBLIC "-//ibatis.apache.org//DTD SQL Map Config 2.0//EN"

"http://ibatis.apache.org/dtd/sql-map-config-2.dtd">

<sqlMapConfig>

<settings cacheModelsEnabled="true" enhancementEnabled="true"

lazyLoadingEnabled="true" errorTracingEnabled="true"

useStatementNamespaces="true"/>

<sqlMap resource="com/lavasoft/stu/jtom/entity/sqlmap/TabB.xml"/>

</sqlMapConfig>

日志的配置:log4j.properties

log4j.rootLogger=INFO,CONSOLE,LOGFILE

log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender

log4j.appender.Threshold=INFO

log4j.appender.CONSOLE.Target=System.out

log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout

log4j.appender.CONSOLE.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss } - %-5p %c %x - %m%n

log4j.appender.LOGFILE=org.apache.log4j.RollingFileAppender

log4j.appender.LOGFILE.File=contestlog.log

log4j.appender.LOGFILE.MaxFileSize=500KB

log4j.appender.LOGFILE.MaxBackupIndex=10

log4j.appender.LOGFILE.layout=org.apache.log4j.PatternLayout

log4j.appender.LOGFILE.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss } - %-p %c %x - %m%n

log4j.logger.com.ibatis=INFO

log4j.logger.com.ibatis.common.jdbc.SimpleDataSource=INFO

log4j.logger.com.ibatis.common.jdbc.ScriptRunner=INFO

log4j.logger.com.ibatis.sqlmap.engine.impl.SqlMapClientDelegate=INFO

log4j.logger.java.sql.Connection=debug

log4j.logger.java.sql.Statement=INFO,CONSOLE

log4j.logger.java.sql.PreparedStatement=INFO,CONSOLE

四、测试

public class Test {

private static ApplicationContext ctx = ApplicationContextUtil.getApplicationContext();

private static StuJotmService ser = (StuJotmService) ctx.getBean("stuJotmService");

public static void test_() {

TabA a = new TabA();

a.setId(1L);

a.setName("aaa");

a.setAddress("address a");

TabB b = new TabB();

b.setId(1L);

b.setName("bbb");

b.setAddress("address b");

ser.saveAB(a, b);

}

public static void main(String[] args) {

test_();

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: