【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数据库连接池
c3p0-config.xml
最后,最重要的com.kdyzm.spring.jdbc.transaction1.applicationContext.xml文件:
(4)测试
由于在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参数。
(4)配置通知,需要制定事务管理器,这里的配置是一个模板,并不针对某个类中的方法,而是针对匹配到的所有方法:
* isolation:制定事务的隔离界别,使用default表示使用数据库制定的隔离级别,spring不再另外指定。
* propagation:指定事务的传播属性,默认是REQUIRED,表示如果当前方法已经在一个事务中运行则加入该事务,否则创建一个新事务。
静态代码+动态变量=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,表示如果当前方法已经在一个事务中运行则加入该事务,否则创建一个新事务。
相关文章推荐
- Java注解阐述
- Mybatis系列(八)集合映射
- Java设计模式之封装算法的模板模式
- ubunt14.04.3的vnc中,ti ccsv5 java异常退出,导致ccsv5崩溃
- Java设计模式之适配器模式
- 深入Java虚拟机笔记---ClassLoader
- Java中的null到底是什么?
- Java学习笔记----封装和private关键字
- equal和==的区别(原理讲解)
- Eclipse 项目导入 Android Studio 导致的乱码问题
- 1 java程序设计概述
- springMVC配置spring AOP功能中遇到的问题
- spring配置文件详解--真的蛮详细
- Java核心技术第4章(1)
- 关于数组的个人理解
- java回收机制
- Generics and Wildcards in Java
- Java学习笔记----匿名对象
- ==和equal()的区别
- 反射3:利用java反射技术将查询结果封装成对象