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

【Java EE 学习 52】【Spring学习第四天】【Spring与JDBC】【JdbcTemplate创建的三种方式】【Spring事务管理】【事务中使用dbutils则回滚失败!!!??】

2015-10-02 21:53 906 查看
一、JDBC编程特点

  静态代码+动态变量=JDBC编程。

  静态代码:比如所有的数据库连接池 都实现了DataSource接口,都实现了Connection接口。

  动态变量:用户名、密码、连接的数据库、表名、SQL语句等信息。

  在spring中动态变量能够通过注入的形式给予。这样的变成方式适合包装成模板。静态代码构成了模板,而动态变量是需要传入的参数。

二、核心类JdbcTemplate

  1.基于模板的设置。

  2.完成了资源的创建和释放的工作。

  3.简化了我们的JDBC操作。

  4.完成了对JDBC的核心流程的工作,包括SQL语句的创建和执行。

  5.仅仅需要传递DataSource就可以将其实例化。

  6.JdbcTemplate只需要创建一次。

  7.JdbcTemplate是线程安全类。

三、使用三种方式将DataSource对象传递给JdbcTemplate,创建JdbcTemplate对象。

  1.第一种方法:继承org.springframework.jdbc.core.support.JdbcDaoSupport类

    (1)首先配置数据源DataSource,这里使用c3p0数据库连接池

<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<constructor-arg index="0" value="namedconfig"></constructor-arg>
</bean>


<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config>
<!-- 默认配置,只可以出现一次 -->
<default-config>
<!-- 连接超时设置30秒 -->
<property name="checkoutTimeout">30000</property>
<!-- 30秒检查一次connection的空闲 -->
<property name="idleConnectionTestPeriod">30</property>
<!--初始化的池大小 -->
<property name="initialPoolSize">2</property>
<!-- 最多的一个connection空闲时间 -->
<property name="maxIdleTime">30</property>
<!-- 最多可以有多少个连接connection -->
<property name="maxPoolSize">10</property>
<!-- 最少的池中有几个连接 -->
<property name="minPoolSize">2</property>
<!-- 批处理的语句-->
<property name="maxStatements">50</property>
<!-- 每次增长几个连接 -->
<property name="acquireIncrement">3</property>
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">
<![CDATA[jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF-8]]>
</property>
<property name="user">root</property>
<property name="password">5a6f38</property>
</default-config>

<named-config name="namedconfig">
<!-- 连接超时设置30秒 -->
<property name="checkoutTimeout">30000</property>
<!-- 30秒检查一次connection的空闲 -->
<property name="idleConnectionTestPeriod">30</property>
<!--初始化的池大小 -->
<property name="initialPoolSize">2</property>
<!-- 最多的一个connection空闲时间 -->
<property name="maxIdleTime">30</property>
<!-- 最多可以有多少个连接connection -->
<property name="maxPoolSize">2</property>
<!-- 最少的池中有几个连接 -->
<property name="minPoolSize">2</property>
<!-- 批处理的语句-->
<property name="maxStatements">50</property>
<!-- 每次增长几个连接 -->
<property name="acquireIncrement">2</property>
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">
<![CDATA[jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF-8]]>
</property>
<property name="user">root</property>
<property name="password">5a6f38</property>
</named-config>
</c3p0-config>


c3p0-config.xml
  最后,最重要的com.kdyzm.spring.jdbc.transaction1.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:context="http://www.springframework.org/schema/context"
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.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
">
<!-- 首先配置数据源 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<constructor-arg index="0" value="namedconfig"></constructor-arg>
</bean>
<!-- 配置JdbcTemplate模板 -->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<constructor-arg index="0">
<ref bean="dataSource"/>
</constructor-arg>
</bean>
<!-- 配置JDBC事务管理器 -->
<bean id="dataSourceTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource">
<ref bean="dataSource"/>
</property>
</bean>

<!-- 配置通知 -->
 <tx:advice id="advice" transaction-manager="dataSourceTransactionManager">
<tx:attributes >
<tx:method name="update*" isolation="DEFAULT" propagation="REQUIRED" read-only="false"/>
</tx:attributes>
</tx:advice>

<!-- 配置切入点 -->
<aop:config>
<!-- <aop:pointcut expression="execution(* com.kdyzm.spring.jdbc.transaction.*ServiceImpl.*(..))" id="perform"/> -->
<aop:pointcut expression="execution(* com.kdyzm.spring.jdbc.transaction1.UserServiceImpl.updateUser(..))" id="perform"/>
 <aop:advisor advice-ref="advice" pointcut-ref="perform"/>
</aop:config>

<!-- 需要注意的是不需要配置切面,因为如果要配置切面的话就需要程序员完成(事务管理),
这样spring就没有意义了 -->

<!-- 程序员需要干的事情! -->
<!-- 需要纳入spring容器的 -->
<bean id="userDao" class="com.kdyzm.spring.jdbc.transaction1.UserDaoImpl">
<property name="jdbcTemplate" ref="jdbcTemplate"></property>
</bean>
<bean id="userService" class="com.kdyzm.spring.jdbc.transaction1.UserServiceImpl">
<property name="userDao" ref="userDao"></property>
</bean>
</beans>


  (4)测试

ApplicationContext context=new ClassPathXmlApplicationContext("com/kdyzm/spring/jdbc/transaction1/applicationContext.xml");
UserService userService = (UserService) context.getBean("userService");
User user=new User();
userService.updateUser(user);


    由于在UserDaoImpl.updateUser方法中存在/0的异常,所以方法会异常终止,但是spring会回滚方法中的事务。通过查看数据库中user的age字段可以得到结果。如果0001和0002并没有发生任何改变,则表示成功回滚;如果只有0001字段发生了自增长,则表示回滚失败。

  6.小练习总结:

    (1)事务的方法中不能使用dbutils工具,否则回滚失败!

    (2)在service层控制事务,目标类是*ServiceImpl,目标方法是update方法。所以配置切入点表达式是:

        <aop:pointcut expression="execution(* com.kdyzm.spring.jdbc.transaction1.UserServiceImpl.updateUser(..))" id="perform"/>

    (3)事务管理器是Jdbc事务管理器,所以使用的类是DataSourceTransactionManager,创建对象的时候需要调用setDataSource方法传入DataSource参数。

<bean id="dataSourceTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource">
<ref bean="dataSource"/>
</property>
</bean>


    (4)配置通知,需要制定事务管理器,这里的配置是一个模板,并不针对某个类中的方法,而是针对匹配到的所有方法:

<tx:advice id="advice" transaction-manager="dataSourceTransactionManager">
<tx:attributes >
<tx:method name="update*" isolation="DEFAULT" propagation="REQUIRED" read-only="false"/>
<tx:method name="*" read-only="true" isolation="DEFAULT" propagation="REQUIRED"/>
</tx:attributes>
</tx:advice>


      * isolation:制定事务的隔离界别,使用default表示使用数据库制定的隔离级别,spring不再另外指定。

      * propagation:指定事务的传播属性,默认是REQUIRED,表示如果当前方法已经在一个事务中运行则加入该事务,否则创建一个新事务。

  

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