Spring_four

Spring_four

基于XML的AOP实现事务控制

坐标xml

  1. <dependencies>
  2. <dependency>
  3. <groupId>org.springframework</groupId>
  4. <artifactId>spring-context</artifactId>
  5. <version>5.0.2.RELEASE</version>
  6. </dependency>
  7. <dependency>
  8. <groupId>org.springframework</groupId>
  9. <artifactId>spring-test</artifactId>
  10. <version>5.0.2.RELEASE</version>
  11. </dependency>
  12. <dependency>
  13. <groupId>commons-dbutils</groupId>
  14. <artifactId>commons-dbutils</artifactId>
  15. <version>1.4</version>
  16. </dependency>
  17. <dependency>
  18. <groupId>mysql</groupId>
  19. <artifactId>mysql-connector-java</artifactId>
  20. <version>5.1.6</version>
  21. </dependency>
  22. <dependency>
  23. <groupId>c3p0</groupId>
  24. <artifactId>c3p0</artifactId>
  25. <version>0.9.1.2</version>
  26. </dependency>
  27. <dependency>
  28. <groupId>junit</groupId>
  29. <artifactId>junit</artifactId>
  30. <version>4.12</version>
  31. </dependency>
  32. <dependency>
  33. <groupId>org.aspectj</groupId>
  34. <artifactId>aspectjweaver</artifactId>
  35. <version>1.8.7</version>
  36. </dependency>
  37. </dependencies>

1562083495746

删除AccountServiceTest测试类上的@Qualifier的注解,不产生代理对象

  1. /**
  2. * 使用Junit单元测试:测试我们的配置
  3. */
  4. @RunWith(SpringJUnit4ClassRunner.class)
  5. @ContextConfiguration(locations = "classpath:applicationContext.xml")
  6. public class AccountServiceTest {
  7. @Autowired
  8. private AccountService as;
  9. @Test
  10. public void testTransfer(){
  11. as.transfer("aaa","bbb",100f);
  12. }
  13. }

此时事务没有控制住


【配置文件】添加spring的aop

applicationContext.xml

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:aop="http://www.springframework.org/schema/aop"
  4. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  5. xsi:schemaLocation="http://www.springframework.org/schema/beans
  6. http://www.springframework.org/schema/beans/spring-beans.xsd
  7. http://www.springframework.org/schema/aop
  8. http://www.springframework.org/schema/aop/spring-aop.xsd">
  9. <!-- 配置Service -->
  10. <bean id="accountService" class="com.it.service.impl.AccountServiceImpl">
  11. <!-- 注入dao -->
  12. <property name="accountDao" ref="accountDao"></property>
  13. <!--注入事务管理器
  14. <property name="txManager" ref="txManager"></property>-->
  15. </bean>
  16. <!--配置Dao对象-->
  17. <bean id="accountDao" class="com.it.dao.impl.AccountDaoImpl">
  18. <!-- 注入QueryRunner -->
  19. <property name="runner" ref="runner"></property>
  20. <!-- 注入ConnectionUtils -->
  21. <property name="connectionUtils" ref="connectionUtils"></property>
  22. </bean>
  23. <!--配置QueryRunner-->
  24. <bean id="runner" class="org.apache.commons.dbutils.QueryRunner" scope="prototype">
  25. <!--<constructor-arg name="ds" ref="dataSource"></constructor-arg>-->
  26. </bean>
  27. <!-- 配置数据源 -->
  28. <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
  29. <!--连接数据库的必备信息-->
  30. <property name="driverClass" value="com.mysql.jdbc.Driver"></property>
  31. <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/itcastspring"></property>
  32. <property name="user" value="root"></property>
  33. <property name="password" value="root"></property>
  34. </bean>
  35. <!-- 配置Connection的工具类 ConnectionUtils -->
  36. <bean id="connectionUtils" class="com.it.utils.ConnectionUtils">
  37. <!-- 注入数据源-->
  38. <property name="dataSource" ref="dataSource"></property>
  39. </bean>
  40. <!-- 配置事务管理器-->
  41. <bean id="txManager" class="com.it.utils.TransactionManager">
  42. <!-- 注入ConnectionUtils -->
  43. <property name="connectionUtils" ref="connectionUtils"></property>
  44. </bean>
  45. <aop:config>
  46. <aop:pointcut id="pc" expression="execution(* com.it.service..*.*(..))"></aop:pointcut>
  47. <aop:aspect ref="txManager">
  48. <!--配置前置通知:开启事务-->
  49. <aop:before method="beginTransaction" pointcut-ref="pc"></aop:before>
  50. <!--配置后置通知:提交事务-->
  51. <aop:after-returning method="commitTransaction" pointcut-ref="pc"></aop:after-returning>
  52. <!--配置异常通知:回滚事务-->
  53. <aop:after-throwing method="rollbackTransaction" pointcut-ref="pc"></aop:after-throwing>
  54. <!--配置最终通知:释放连接-->
  55. <aop:after method="closeTransaction" pointcut-ref="pc"></aop:after>
  56. </aop:aspect>
  57. </aop:config>
  58. </beans>

【注解】添加spring的aop

可以使用【前置通知】、【后置通知】、【异常通知】、【最终通知】

坐标

  1. <dependencies>
  2. <dependency>
  3. <groupId>org.springframework</groupId>
  4. <artifactId>spring-context</artifactId>
  5. <version>5.0.2.RELEASE</version>
  6. </dependency>
  7. <dependency>
  8. <groupId>org.springframework</groupId>
  9. <artifactId>spring-test</artifactId>
  10. <version>5.0.2.RELEASE</version>
  11. </dependency>
  12. <dependency>
  13. <groupId>commons-dbutils</groupId>
  14. <artifactId>commons-dbutils</artifactId>
  15. <version>1.4</version>
  16. </dependency>
  17. <dependency>
  18. <groupId>mysql</groupId>
  19. <artifactId>mysql-connector-java</artifactId>
  20. <version>5.1.6</version>
  21. </dependency>
  22. <dependency>
  23. <groupId>c3p0</groupId>
  24. <artifactId>c3p0</artifactId>
  25. <version>0.9.1.2</version>
  26. </dependency>
  27. <dependency>
  28. <groupId>junit</groupId>
  29. <artifactId>junit</artifactId>
  30. <version>4.12</version>
  31. </dependency>
  32. <dependency>
  33. <groupId>org.aspectj</groupId>
  34. <artifactId>aspectjweaver</artifactId>
  35. <version>1.8.7</version>
  36. </dependency>
  37. </dependencies>

配置AccountServiceImpl.java的注解

  1. @Service
  2. public class AccountServiceImpl implements AccountService {
  3. @Autowired
  4. private AccountDao accountDao;
  5. }

配置AccountDaoImpl.java的注解

  1. @Repository
  2. public class AccountDaoImpl implements AccountDao {
  3. @Autowired
  4. private QueryRunner runner;
  5. @Autowired
  6. private ConnectionUtils connectionUtils;
  7. }

配置ConnectionUtils.java的注解

  1. @Component
  2. public class ConnectionUtils {
  3. private ThreadLocal<Connection> tl = new ThreadLocal<Connection>();
  4. @Autowired
  5. private DataSource dataSource;
  6. }

配置TransactionManager.java的注解

  1. @Component
  2. @Aspect // 切面
  3. public class TransactionManager {
  4. @Autowired
  5. private ConnectionUtils connectionUtils;
  6. @Pointcut(value = "execution(* com.it.service..*.*(..))") // 切入点
  7. public void pc(){};
  8. /**
  9. * 开启事务
  10. */
  11. @Before(value = "pc()")
  12. public void beginTransaction(){
  13. try {
  14. System.out.println("前置通知");
  15. connectionUtils.getThreadConnection().setAutoCommit(false);
  16. }catch (Exception e){
  17. e.printStackTrace();
  18. }
  19. }
  20. /**
  21. * 提交事务
  22. */
  23. @AfterReturning(value = "pc()")
  24. public void commit(){
  25. try {
  26. System.out.println("后置通知");
  27. connectionUtils.getThreadConnection().commit();
  28. }catch (Exception e){
  29. e.printStackTrace();
  30. }
  31. }
  32. /**
  33. * 回滚事务
  34. */
  35. @AfterThrowing(value = "pc()")
  36. public void rollback(){
  37. try {
  38. System.out.println("异常通知");
  39. connectionUtils.getThreadConnection().rollback();
  40. }catch (Exception e){
  41. e.printStackTrace();
  42. }
  43. }
  44. /**
  45. * 释放连接
  46. */
  47. @After(value = "pc()")
  48. public void release(){
  49. try {
  50. System.out.println("最终通知");
  51. connectionUtils.getThreadConnection().close();//把连接还回连接池中
  52. connectionUtils.removeConnection();
  53. }catch (Exception e){
  54. e.printStackTrace();
  55. }
  56. }
  57. }

配置spring容器

配置applicationContext.xml

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:aop="http://www.springframework.org/schema/aop"
  4. xmlns:context="http://www.springframework.org/schema/context"
  5. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  6. xsi:schemaLocation="http://www.springframework.org/schema/beans
  7. http://www.springframework.org/schema/beans/spring-beans.xsd
  8. http://www.springframework.org/schema/aop
  9. http://www.springframework.org/schema/aop/spring-aop.xsd
  10. http://www.springframework.org/schema/context
  11. http://www.springframework.org/schema/context/spring-context.xsd">
  12. <!--开启注解支持的组件扫描-->
  13. <context:component-scan base-package="com.it"></context:component-scan>
  14. <!--开启aop的注解支持-->
  15. <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
  16. <!--配置QueryRunner-->
  17. <bean id="runner" class="org.apache.commons.dbutils.QueryRunner" scope="prototype">
  18. <!--<constructor-arg name="ds" ref="dataSource"></constructor-arg>-->
  19. </bean>
  20. <!-- 配置数据源 -->
  21. <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
  22. <!--连接数据库的必备信息-->
  23. <property name="driverClass" value="com.mysql.jdbc.Driver"></property>
  24. <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/itcastspring"></property>
  25. <property name="user" value="root"></property>
  26. <property name="password" value="root"></property>
  27. </bean>
  28. </beans>

text

  1. @RunWith(SpringJUnit4ClassRunner.class)
  2. @ContextConfiguration(locations = "classpath:applicationContext.xml")
  3. public class AccountServiceTest {
  4. @Autowired
  5. private AccountService as;
  6. @Test
  7. public void testTransfer(){
  8. as.transfer("aaa","bbb",100f);
  9. }
  10. }

但是发现,抛出异常。

1562083852643

因为注解的方式执行顺序是【前置通知】、【最终通知】、【异常通知】/【后置通知】

1562083867841

我们需要使用环绕通知解决问题。

配置TransactionManager.java

  1. @Component
  2. @Aspect
  3. public class TransactionManager {
  4. @Autowired
  5. private ConnectionUtils connectionUtils;
  6. @Pointcut(value = "execution(* com.it.service..*.*(..))")
  7. public void pc(){};
  8. /**
  9. * 开启事务
  10. */
  11. //@Before(value = "pc()")
  12. public void beginTransaction(){
  13. try {
  14. System.out.println("前置通知");
  15. connectionUtils.getThreadConnection().setAutoCommit(false);
  16. }catch (Exception e){
  17. e.printStackTrace();
  18. }
  19. }
  20. /**
  21. * 提交事务
  22. */
  23. //@AfterReturning(value = "pc()")
  24. public void commit(){
  25. try {
  26. System.out.println("后置通知");
  27. connectionUtils.getThreadConnection().commit();
  28. }catch (Exception e){
  29. e.printStackTrace();
  30. }
  31. }
  32. /**
  33. * 回滚事务
  34. */
  35. //@AfterThrowing(value = "pc()")
  36. public void rollback(){
  37. try {
  38. System.out.println("异常通知");
  39. connectionUtils.getThreadConnection().rollback();
  40. }catch (Exception e){
  41. e.printStackTrace();
  42. }
  43. }
  44. /**
  45. * 释放连接
  46. */
  47. //@After(value = "pc()")
  48. public void release(){
  49. try {
  50. System.out.println("最终通知");
  51. connectionUtils.getThreadConnection().close();//把连接还回连接池中
  52. connectionUtils.removeConnection();
  53. }catch (Exception e){
  54. e.printStackTrace();
  55. }
  56. }
  57. @Around(value="pc()")
  58. public Object around(ProceedingJoinPoint joinPoint){
  59. Object returnValue = null;
  60. try {
  61. this.beginTransaction(); // 开启事务
  62. returnValue = joinPoint.proceed(joinPoint.getArgs());
  63. this.commit(); // 提交事务
  64. } catch (Throwable throwable) {
  65. throwable.printStackTrace();
  66. this.rollback(); // 回滚事务
  67. }
  68. finally {
  69. this.release(); // 释放资源
  70. }
  71. return returnValue;
  72. }
  73. }

Spring中的JdbcTemplate

1\dbcTemplate概述

它是spring框架中提供的一个对象,是对原始Jdbc API对象的简单封装。spring框架为我们提供了很多的操作模板类。

操作关系型数据的:

JdbcTemplate (操作JDBC,操作数据库)

HibernateTemplate (操作hibernate,操作数据库)

操作nosql数据库的: RedisTemplate(操作Redis,非关系型数据库)

操作消息队列(MQ)的: JmsTemplate (操作ActiveMQ,消息队列)

* 短信平台

* 邮件平台

操作索引库的:ElasticSearchTemplate(操作ElasticSearch,全文检索)

我们今天的主角在spring-jdbc-5.0.2.RELEASE.jar中,我们在导包的时候,除了要导入这个jar包外,还需要导入一个spring-tx-5.0.2.RELEASE.jar(它是和事务相关的)。


坐标xml

  1. <dependencies>
  2. <dependency>
  3. <groupId>org.springframework</groupId>
  4. <artifactId>spring-context</artifactId>
  5. <version>5.0.2.RELEASE</version>
  6. </dependency>
  7. <dependency>
  8. <groupId>org.springframework</groupId>
  9. <artifactId>spring-jdbc</artifactId>
  10. <version>5.0.2.RELEASE</version>
  11. </dependency>
  12. <dependency>
  13. <groupId>org.springframework</groupId>
  14. <artifactId>spring-tx</artifactId>
  15. <version>5.0.2.RELEASE</version>
  16. </dependency>
  17. <dependency>
  18. <groupId>mysql</groupId>
  19. <artifactId>mysql-connector-java</artifactId>
  20. <version>5.1.6</version>
  21. </dependency>
  22. </dependencies>

创建类Account.java

  1. /**
  2. * 账户的实体类
  3. */
  4. public class Account implements Serializable {
  5. private Integer id;
  6. private String name;
  7. private Float money;
  8. }

创建类JdbcTemplateDemo1.java

使用spring提供的数据源

  1. /**
  2. * JdbcTemplate的最基本用法
  3. */
  4. public class JdbcTemplateDemo1 {
  5. public static void main(String[] args) {
  6. //准备数据源:spring的内置数据源
  7. DriverManagerDataSource ds = new DriverManagerDataSource();
  8. ds.setDriverClassName("com.mysql.jdbc.Driver");
  9. ds.setUrl("jdbc:mysql://localhost:3306/itcastspring");
  10. ds.setUsername("root");
  11. ds.setPassword("root");
  12. //1.创建JdbcTemplate对象
  13. JdbcTemplate jt = new JdbcTemplate();
  14. //给jt设置数据源
  15. jt.setDataSource(ds);
  16. //2.执行操作
  17. jt.execute("insert into account(name,money)values('ccc',1000)");
  18. }
  19. }

2\使用spring容器创建数据源和JdbcTemplate

配置applicationContext.xml

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://www.springframework.org/schema/beans
  5. http://www.springframework.org/schema/beans/spring-beans.xsd">
  6. <!--配置JdbcTemplate-->
  7. <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
  8. <property name="dataSource" ref="dataSource"></property>
  9. </bean>
  10. <!-- 配置数据源-->
  11. <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
  12. <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
  13. <property name="url" value="jdbc:mysql://localhost:3306/itcastspring"></property>
  14. <property name="username" value="root"></property>
  15. <property name="password" value="root"></property>
  16. </bean>
  17. </beans>

创建JdbcTemplateDemo2.java

  1. /**
  2. * JdbcTemplate的最基本用法
  3. */
  4. public class JdbcTemplateDemo2 {
  5. public static void main(String[] args) {
  6. //1.获取容器
  7. ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
  8. //2.获取对象
  9. JdbcTemplate jt = ac.getBean("jdbcTemplate",JdbcTemplate.class);
  10. //3.执行操作
  11. jt.execute("insert into account(name,money)values('eee',2222)");
  12. /* //准备数据源:spring的内置数据源
  13. DriverManagerDataSource ds = new DriverManagerDataSource();
  14. ds.setDriverClassName("com.mysql.jdbc.Driver");
  15. ds.setUrl("jdbc:mysql://localhost:3306/eesy");
  16. ds.setUsername("root");
  17. ds.setPassword("1234");
  18. //1.创建JdbcTemplate对象
  19. JdbcTemplate jt = new JdbcTemplate();
  20. //给jt设置数据源
  21. jt.setDataSource(ds);
  22. //2.执行操作
  23. jt.execute("insert into account(name,money)values('ccc',1000)");*/
  24. }
  25. }

3\使用JdbcTemplate操作数据库的CRUD

创建测试类JdbcTemplateDemo3.java

  1. /**
  2. * JdbcTemplate的CRUD操作
  3. */
  4. public class JdbcTemplateDemo3 {
  5. public static void main(String[] args) {
  6. //1.获取容器
  7. ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
  8. //2.获取对象
  9. JdbcTemplate jt = ac.getBean("jdbcTemplate",JdbcTemplate.class);
  10. //3.执行操作
  11. //保存
  12. // jt.update("insert into account(name,money)values(?,?)","eee",3333f);
  13. //更新
  14. // jt.update("update account set name=?,money=? where id=?","test",4567,7);
  15. //删除
  16. // jt.update("delete from account where id=?",3);
  17. //查询所有
  18. // List<Account> accounts = jt.query("select * from account where money > ?",new AccountRowMapper(),1000f);
  19. // List<Account> accounts = jt.query("select * from account where money > ?",new BeanPropertyRowMapper<Account>(Account.class),1000f);
  20. // for(Account account : accounts){
  21. // System.out.println(account);
  22. // }
  23. //查询一个
  24. // List<Account> accounts = jt.query("select * from account where id = ?",new BeanPropertyRowMapper<Account>(Account.class),1);
  25. // System.out.println(accounts.isEmpty()?"没有内容":accounts.get(0));
  26. // Account account = jt.queryForObject("select * from account where id = ?", new BeanPropertyRowMapper<Account>(Account.class),1);
  27. // System.out.println(account);
  28. //查询返回一行一列(使用聚合函数)
  29. // Long count = jt.queryForObject("select count(*) from account where money > ?",Long.class,1000f);
  30. // System.out.println(count);
  31. }
  32. }
  33. /**
  34. * 定义Account的封装策略(解决实体的属性和数据库的字段名称不一致)
  35. */
  36. class AccountRowMapper implements RowMapper<Account> {
  37. /**
  38. * 把结果集中的数据封装到Account中,然后由spring把每个Account加到集合中
  39. * @param rs
  40. * @param rowNum
  41. * @return
  42. * @throws SQLException
  43. */
  44. public Account mapRow(ResultSet rs, int rowNum) throws SQLException {
  45. Account account = new Account();
  46. account.setId(rs.getInt("id"));
  47. account.setName(rs.getString("name"));
  48. account.setMoney(rs.getFloat("money"));
  49. return account;
  50. }
  51. }

4\ JdbcTemplate操作Dao

创建AccountDao接口

  1. /**
  2. * 账户的持久层接口
  3. */
  4. public interface AccountDao {
  5. /**
  6. * 根据Id查询账户
  7. * @param accountId
  8. * @return
  9. */
  10. Account findAccountById(Integer accountId);
  11. /**
  12. * 根据名称查询账户
  13. * @param accountName
  14. * @return
  15. */
  16. Account findAccountByName(String accountName);
  17. /**
  18. * 更新账户
  19. * @param account
  20. */
  21. void updateAccount(Account account);
  22. }

创建接口的实现类AccountDaoImpl.java

  1. /**
  2. * 账户的持久层实现类
  3. */
  4. public class AccountDaoImpl implements AccountDao {
  5. JdbcTemplate jdbcTemplate;
  6. public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
  7. this.jdbcTemplate = jdbcTemplate;
  8. }
  9. public Account findAccountById(Integer accountId) {
  10. List<Account> accounts = jdbcTemplate.query("select * from account where id = ?",new BeanPropertyRowMapper<Account>(Account.class),accountId);
  11. return accounts.isEmpty()?null:accounts.get(0);
  12. }
  13. public Account findAccountByName(String accountName) {
  14. List<Account> accounts = jdbcTemplate.query("select * from account where name = ?",new BeanPropertyRowMapper<Account>(Account.class),accountName);
  15. if(accounts.isEmpty()){
  16. return null;
  17. }
  18. if(accounts.size()>1){
  19. throw new RuntimeException("结果集不唯一");
  20. }
  21. return accounts.get(0);
  22. }
  23. public void updateAccount(Account account) {
  24. jdbcTemplate.update("update account set name=?,money=? where id=?",account.getName(),account.getMoney(),account.getId());
  25. }
  26. }

applicationContext.xml

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://www.springframework.org/schema/beans
  5. http://www.springframework.org/schema/beans/spring-beans.xsd">
  6. <!-- 配置账户的持久层-->
  7. <bean id="accountDao" class="com.it.dao.impl.AccountDaoImpl">
  8. <property name="jdbcTemplate" ref="jdbcTemplate"></property>
  9. </bean>
  10. <!--配置JdbcTemplate-->
  11. <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
  12. <property name="dataSource" ref="dataSource"></property>
  13. </bean>
  14. <!-- 配置数据源-->
  15. <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
  16. <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
  17. <property name="url" value="jdbc:mysql://localhost:3306/itcastspring"></property>
  18. <property name="username" value="root"></property>
  19. <property name="password" value="root"></property>
  20. </bean>
  21. </beans>

test

  1. /**
  2. * JdbcTemplate的最基本用法
  3. */
  4. public class JdbcTemplateDemo4 {
  5. public static void main(String[] args) {
  6. //1.获取容器
  7. ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
  8. //2.获取对象
  9. AccountDao accountDao = ac.getBean("accountDao",AccountDao.class);
  10. Account account = accountDao.findAccountById(1);
  11. System.out.println(account);
  12. account.setMoney(30000f);
  13. accountDao.updateAccount(account);
  14. }
  15. }

5\ Spring提供JdbcDaoSupport的使用

使用AccountDaoImpl继承JdbcDaoSupport,实现AccountDao

  1. /**
  2. * 账户的持久层实现类
  3. */
  4. public class AccountDaoImpl extends JdbcDaoSupport implements AccountDao {
  5. public Account findAccountById(Integer accountId) {
  6. List<Account> accounts = super.getJdbcTemplate().query("select * from account where id = ?",new BeanPropertyRowMapper<Account>(Account.class),accountId);
  7. return accounts.isEmpty()?null:accounts.get(0);
  8. }
  9. public Account findAccountByName(String accountName) {
  10. List<Account> accounts = super.getJdbcTemplate().query("select * from account where name = ?",new BeanPropertyRowMapper<Account>(Account.class),accountName);
  11. if(accounts.isEmpty()){
  12. return null;
  13. }
  14. if(accounts.size()>1){
  15. throw new RuntimeException("结果集不唯一");
  16. }
  17. return accounts.get(0);
  18. }
  19. public void updateAccount(Account account) {
  20. super.getJdbcTemplate().update("update account set name=?,money=? where id=?",account.getName(),account.getMoney(),account.getId());
  21. }
  22. }

applicationContext.xml

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://www.springframework.org/schema/beans
  5. http://www.springframework.org/schema/beans/spring-beans.xsd">
  6. <!-- 配置账户的持久层-->
  7. <bean id="accountDao" class="com.it.dao.impl.AccountDaoImpl">
  8. <!--<property name="jdbcTemplate" ref="jdbcTemplate"></property>-->
  9. <property name="dataSource" ref="dataSource"></property>
  10. </bean>
  11. <!--配置JdbcTemplate
  12. <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
  13. <property name="dataSource" ref="dataSource"></property>
  14. </bean>
  15. -->
  16. <!-- 配置数据源-->
  17. <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
  18. <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
  19. <property name="url" value="jdbc:mysql://localhost:3306/itcastspring"></property>
  20. <property name="username" value="root"></property>
  21. <property name="password" value="root"></property>
  22. </bean>
  23. </beans>

test

  1. /**
  2. * JdbcTemplate的最基本用法
  3. */
  4. public class JdbcTemplateDemo5 {
  5. public static void main(String[] args) {
  6. //1.获取容器
  7. ApplicationContext ac = new
  8. ClassPathXmlApplicationContext("applicationContext.xml");
  9. //2.获取对象
  10. AccountDao accountDao = ac.getBean("accountDao",AccountDao.class);
  11. Account account = accountDao.findAccountById(1);
  12. System.out.println(account);
  13. account.setMoney(30000f);
  14. accountDao.updateAccount(account);
  15. }
  16. }

6\ 使用JdbcDaoSupport的注解开发

创建AccountDao接口

  1. /**
  2. * 账户的持久层接口
  3. */
  4. public interface AccountDao {
  5. /**
  6. * 根据Id查询账户
  7. * @param accountId
  8. * @return
  9. */
  10. Account findAccountById(Integer accountId);
  11. /**
  12. * 根据名称查询账户
  13. * @param accountName
  14. * @return
  15. */
  16. Account findAccountByName(String accountName);
  17. /**
  18. * 更新账户
  19. * @param account
  20. */
  21. void updateAccount(Account account);
  22. }

创建AccountDaoImpl2实现AccountDao

  1. /**
  2. * 账户的持久层实现类
  3. */
  4. @Repository("accountDao")
  5. public class AccountDaoImpl2 extends JdbcDaoSupport implements AccountDao {
  6. @Autowired // 放置到属性上,也可以放置到set方法上(将spring容器中创建的对象,通过set方法的形参传递给该方法)
  7. public void setDi(DataSource dataSource){
  8. super.setDataSource(dataSource);
  9. }
  10. public Account findAccountById(Integer accountId) {
  11. List<Account> accounts = jdbcTemplate.query("select * from account where id = ?",new BeanPropertyRowMapper<Account>(Account.class),accountId);
  12. return accounts.isEmpty()?null:accounts.get(0);
  13. }
  14. public Account findAccountByName(String accountName) {
  15. List<Account> accounts = jdbcTemplate.query("select * from account where name = ?",new BeanPropertyRowMapper<Account>(Account.class),accountName);
  16. if(accounts.isEmpty()){
  17. return null;
  18. }
  19. if(accounts.size()>1){
  20. throw new RuntimeException("结果集不唯一");
  21. }
  22. return accounts.get(0);
  23. }
  24. public void updateAccount(Account account) {
  25. jdbcTemplate.update("update account set name=?,money=? where id=?",account.getName(),account.getMoney(),account.getId());
  26. }
  27. }

applicationContext-anno.xml

重新创建applicationContext-anno.xml演示,表示使用注解

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:context="http://www.springframework.org/schema/context"
  4. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  5. xsi:schemaLocation="http://www.springframework.org/schema/beans
  6. http://www.springframework.org/schema/beans/spring-beans.xsd
  7. http://www.springframework.org/schema/context
  8. http://www.springframework.org/schema/context/spring-context.xsd">
  9. <context:component-scan base-package="com.it"></context:component-scan>
  10. <!-- 配置数据源-->
  11. <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
  12. <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
  13. <property name="url" value="jdbc:mysql://localhost:3306/itcastspring"></property>
  14. <property name="username" value="root"></property>
  15. <property name="password" value="root"></property>
  16. </bean>
  17. </beans>

test

  1. /**
  2. * JdbcTemplate的最基本用法,使用注解
  3. */
  4. public class JdbcTemplateDemo5 {
  5. public static void main(String[] args) {
  6. //1.获取容器
  7. ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext-anno.xml");
  8. //2.获取对象
  9. AccountDao accountDao = ac.getBean("accountDao",AccountDao.class);
  10. Account account = accountDao.findAccountById(1);
  11. System.out.println(account);
  12. account.setMoney(30000f);
  13. accountDao.updateAccount(account);
  14. }
  15. }

Spring中的事务控制

1.1 Spring事务控制我们要明确的

第一:JavaEE体系进行分层开发,事务处理位于业务层,Spring提供了分层设计业务层的事务处理解决方案。

第二:spring框架为我们提供了一组事务控制的接口 。具体在后面的第二小节介绍。这组接口是在spring-tx-5.0.2.RELEASE.jar中。

第三:spring的事务控制都是基于AOP的,它既可以使用编程的方式实现,也可以使用配置的方式(声明式)实现。我们学习的重点是使用配置(声明式事务处理)的方式实现。

1.2 Spring中事务控制的API介绍

1.2.1 PlatformTransactionManager

此接口是spring的事务管理器,它里面提供了我们常用的操作事务的方法,如下图:

img

我们在开发中都是使用它的实现类:

真正管理事务的对象

org.springframework.jdbc.datasource.DataSourceTransactionManager 使用Spring JDBC或myBatis 进行持久化数据时使用

org.springframework.orm.hibernate5.HibernateTransactionManager 使用Hibernate版本进行持久化数据时使用

JpaTransactionManager,使用Jpa操作持久化数据时使用

1.2.2 TransactionDefinition

它是事务的定义信息对象,里面有如下方法:

img

1:事务的隔离级别

2img

2:事务的传播行为

REQUIRED:如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中。一般的选择(默认值)

SUPPORTS:支持当前事务,如果当前没有事务,就以非事务方式执行(没有事务)

MANDATORY:使用当前的事务,如果当前没有事务,就抛出异常

REQUERS_NEW:新建事务,如果当前在事务中,把当前事务挂起,从新开启一个新的事务。

NOT_SUPPORTED:以非事务方式执行操作,如果当前存在事务,就把当前事务挂起

NEVER:以非事务方式运行,如果当前存在事务,抛出异常

NESTED:如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行REQUIRED类似的操作。

3:事务超时时间

默认值是-1,没有超时限制。如果有,以秒为单位、会进行设置,在事务提交/回滚后多长时间,事务失效。

4:是否是只读事务

建议查询时设置为只读。

增删改设置可写。

1.2.3TransactionStatus(了解)

此接口提供的是事务具体的运行状态,方法介绍如下图:

img


Spring的编程式事务处理

坐标xml

  1. <dependencies>
  2. <dependency>
  3. <groupId>org.springframework</groupId>
  4. <artifactId>spring-context</artifactId>
  5. <version>5.0.2.RELEASE</version>
  6. </dependency>
  7. <dependency>
  8. <groupId>org.springframework</groupId>
  9. <artifactId>spring-jdbc</artifactId>
  10. <version>5.0.2.RELEASE</version>
  11. </dependency>
  12. <dependency>
  13. <groupId>org.springframework</groupId>
  14. <artifactId>spring-tx</artifactId>
  15. <version>5.0.2.RELEASE</version>
  16. </dependency>
  17. <dependency>
  18. <groupId>org.springframework</groupId>
  19. <artifactId>spring-test</artifactId>
  20. <version>5.0.2.RELEASE</version>
  21. </dependency>
  22. <dependency>
  23. <groupId>mysql</groupId>
  24. <artifactId>mysql-connector-java</artifactId>
  25. <version>5.1.6</version>
  26. </dependency>
  27. <dependency>
  28. <groupId>org.aspectj</groupId>
  29. <artifactId>aspectjweaver</artifactId>
  30. <version>1.8.7</version>
  31. </dependency>
  32. <dependency>
  33. <groupId>junit</groupId>
  34. <artifactId>junit</artifactId>
  35. <version>4.12</version>
  36. </dependency>
  37. </dependencies>

AccountDao.java

  1. /**
  2. * 账户的持久层接口
  3. */
  4. public interface AccountDao {
  5. /**
  6. * 根据Id查询账户
  7. * @param accountId
  8. * @return
  9. */
  10. Account findAccountById(Integer accountId);
  11. /**
  12. * 根据名称查询账户
  13. * @param accountName
  14. * @return
  15. */
  16. Account findAccountByName(String accountName);
  17. /**
  18. * 更新账户
  19. * @param account
  20. */
  21. void updateAccount(Account account);
  22. }

AccountDaoImpl.java

  1. /**
  2. * 账户的持久层实现类
  3. */
  4. public class AccountDaoImpl extends JdbcDaoSupport implements AccountDao {
  5. public Account findAccountById(Integer accountId) {
  6. List<Account> accounts = this.getJdbcTemplate().query("select * from account where id = ?",new BeanPropertyRowMapper<Account>(Account.class),accountId);
  7. return accounts.isEmpty()?null:accounts.get(0);
  8. }
  9. public Account findAccountByName(String accountName) {
  10. List<Account> accounts = this.getJdbcTemplate().query("select * from account where name = ?",new BeanPropertyRowMapper<Account>(Account.class),accountName);
  11. if(accounts.isEmpty()){
  12. return null;
  13. }
  14. if(accounts.size()>1){
  15. throw new RuntimeException("结果集不唯一");
  16. }
  17. return accounts.get(0);
  18. }
  19. public void updateAccount(Account account) {
  20. this.getJdbcTemplate().update("update account set name=?,money=? where id=?",account.getName(),account.getMoney(),account.getId());
  21. }
  22. }

AccountService.java

  1. /**
  2. * 账户的业务层接口
  3. */
  4. public interface AccountService {
  5. /**
  6. * 根据id查询账户信息
  7. * @param accountId
  8. * @return
  9. */
  10. Account findAccountById(Integer accountId);
  11. /**
  12. * 转账
  13. * @param sourceName 转成账户名称
  14. * @param targetName 转入账户名称
  15. * @param money 转账金额
  16. */
  17. void transfer(String sourceName, String targetName, Float money);
  18. }

AccountServiceImpl.java

  1. /**
  2. * 账户的业务层实现类
  3. *
  4. * 事务控制应该都是在业务层
  5. */
  6. public class AccountServiceImpl implements AccountService {
  7. private AccountDao accountDao;
  8. public void setAccountDao(AccountDao accountDao) {
  9. this.accountDao = accountDao;
  10. }
  11. public Account findAccountById(Integer accountId) {
  12. return accountDao.findAccountById(accountId);
  13. }
  14. public void transfer(String sourceName, String targetName, Float money) {
  15. System.out.println("transfer....");
  16. //2.1根据名称查询转出账户
  17. Account source = accountDao.findAccountByName(sourceName);
  18. //2.2根据名称查询转入账户
  19. Account target = accountDao.findAccountByName(targetName);
  20. //2.3转出账户减钱
  21. source.setMoney(source.getMoney()-money);
  22. //2.4转入账户加钱
  23. target.setMoney(target.getMoney()+money);
  24. //2.5更新转出账户
  25. accountDao.updateAccount(source);
  26. int i=1/0;
  27. //2.6更新转入账户
  28. accountDao.updateAccount(target);
  29. }
  30. }

applicationContext.xml

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:context="http://www.springframework.org/schema/context"
  4. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  5. xsi:schemaLocation="http://www.springframework.org/schema/beans
  6. http://www.springframework.org/schema/beans/spring-beans.xsd
  7. http://www.springframework.org/schema/context
  8. http://www.springframework.org/schema/context/spring-context.xsd">
  9. <!-- 配置账户的业务层-->
  10. <bean id="accountService" class="com.it.service.impl.AccountServiceImpl">
  11. <property name="accountDao" ref="accountDao"></property>
  12. </bean>
  13. <!-- 配置账户的持久层-->
  14. <bean id="accountDao" class="com.it.dao.impl.AccountDaoImpl">
  15. <property name="dataSource" ref="dataSource"></property>
  16. </bean>
  17. <!-- 配置数据源-->
  18. <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
  19. <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
  20. <property name="url" value="jdbc:mysql://localhost:3306/itcastspring"></property>
  21. <property name="username" value="root"></property>
  22. <property name="password" value="root"></property>
  23. </bean>
  24. </beans>

test

  1. @RunWith(SpringJUnit4ClassRunner.class)
  2. @ContextConfiguration(locations = "classpath:applicationContext.xml")
  3. public class AccountServiceTest {
  4. @Autowired
  5. private AccountService as;
  6. @Test
  7. public void testTransfer() {
  8. as.transfer("aaa", "bbb", 100f);
  9. }
  10. }

编程式事务控制

Jdbc的操作,需要配置Jdbc的事务管理器

配置applicationContext.xml

  1. <!-- 一:配置事务管理器=============== -->
  2. <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
  3. <property name="dataSource" ref="dataSource"/>
  4. </bean>

配置事务管理模板

配置applicationContext.xml

  1. <!-- 二:配置事务管理的模板 -->
  2. <bean id="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate">
  3. <property name="transactionManager" ref="transactionManager"/>
  4. </bean>

在业务层注入事务管理模板

配置applicationContext-tx1.xml

  1. <!-- 配置账户的业务层-->
  2. <bean id="accountService" class="com.it.service.impl.AccountServiceImpl">
  3. <property name="accountDao" ref="accountDao"></property>
  4. <property name="transactionTemplate" ref="transactionTemplate"/>
  5. </bean>

AccountServiceImpl.java

  1. public class AccountServiceImpl implements AccountService {
  2. // 注入事务管理的模板
  3. private TransactionTemplate transactionTemplate;
  4. public void setTransactionTemplate(TransactionTemplate transactionTemplate) {
  5. this.transactionTemplate = transactionTemplate;
  6. }
  7. private AccountDao accountDao;
  8. public void setAccountDao(AccountDao accountDao) {
  9. this.accountDao = accountDao;
  10. }
  11. public Account findAccountById(Integer accountId) {
  12. return accountDao.findAccountById(accountId);
  13. }
  14. public void transfer(final String sourceName, final String targetName, final Float money) {
  15. System.out.println("transfer....");
  16. transactionTemplate.execute(new TransactionCallbackWithoutResult() {
  17. @Override
  18. protected void doInTransactionWithoutResult(TransactionStatus transactionStatus) {
  19. System.out.println(transactionStatus.isNewTransaction() + " "+transactionStatus.isCompleted());
  20. //2.1根据名称查询转出账户
  21. Account source = accountDao.findAccountByName(sourceName);
  22. //2.2根据名称查询转入账户
  23. Account target = accountDao.findAccountByName(targetName);
  24. //2.3转出账户减钱
  25. source.setMoney(source.getMoney()-money);
  26. //2.4转入账户加钱
  27. target.setMoney(target.getMoney()+money);
  28. //2.5更新转出账户
  29. accountDao.updateAccount(source);
  30. // int i=1/0;
  31. //2.6更新转入账户
  32. accountDao.updateAccount(target);
  33. }
  34. });
  35. }
  36. }

Spring的声明式事务处理(**)

配置applicationContext.xml

同时去掉:TransactionTemplate的操作

1562085156877

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:context="http://www.springframework.org/schema/context"
  4. xmlns:aop="http://www.springframework.org/schema/aop"
  5. xmlns:tx="http://www.springframework.org/schema/tx"
  6. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  7. xsi:schemaLocation="http://www.springframework.org/schema/beans
  8. http://www.springframework.org/schema/beans/spring-beans.xsd
  9. http://www.springframework.org/schema/context
  10. http://www.springframework.org/schema/context/spring-context.xsd
  11. http://www.springframework.org/schema/aop
  12. http://www.springframework.org/schema/aop/spring-aop.xsd
  13. http://www.springframework.org/schema/tx
  14. http://www.springframework.org/schema/tx/spring-tx.xsd">
  15. <!-- 配置账户的业务层-->
  16. <bean id="accountService" class="com.it.service.impl.AccountServiceImpl">
  17. <property name="accountDao" ref="accountDao"></property>
  18. </bean>
  19. <!-- 配置账户的持久层-->
  20. <bean id="accountDao" class="com.it.dao.impl.AccountDaoImpl">
  21. <property name="dataSource" ref="dataSource"></property>
  22. </bean>
  23. <!-- 配置数据源-->
  24. <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
  25. <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
  26. <property name="url" value="jdbc:mysql://localhost:3306/itcastspring"></property>
  27. <property name="username" value="root"></property>
  28. <property name="password" value="root"></property>
  29. </bean>
  30. <!-- spring中基于XML的声明式事务控制配置步骤
  31. 1、配置事务管理器
  32. 2、配置事务的通知
  33. 此时我们需要导入事务的约束 tx名称空间和约束,同时也需要aop的
  34. 使用tx:advice标签配置事务通知
  35. 属性:
  36. id:给事务通知起一个唯一标识
  37. transaction-manager:给事务通知提供一个事务管理器引用
  38. 3、配置AOP中的通用切入点表达式
  39. 4、建立事务通知和切入点表达式的对应关系
  40. 5、配置事务的属性
  41. 是在事务的通知tx:advice标签的内部
  42. -->
  43. <!-- 一:配置事务管理器 -->
  44. <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
  45. <property name="dataSource" ref="dataSource"></property>
  46. </bean>
  47. <!-- 二:配置事务的通知-->
  48. <tx:advice id="txAdvice" transaction-manager="transactionManager">
  49. <!-- 配置事务的属性
  50. isolation:用于指定事务的隔离级别。默认值是DEFAULT,表示使用数据库的默认隔离级别。
  51. propagation:用于指定事务的传播行为。默认值是REQUIRED,表示一定会有事务,增删改的选择。查询方法可以选择SUPPORTS。
  52. read-only:用于指定事务是否只读。只有查询方法才能设置为true。默认值是false,表示读写。
  53. timeout:用于指定事务的超时时间,默认值是-1,表示永不超时。如果指定了数值,以秒为单位。
  54. rollback-for:用于指定一个异常,当产生该异常时,事务回滚,产生其他异常时,事务不回滚。没有默认值。表示任何异常都回滚。
  55. no-rollback-for:用于指定一个异常,当产生该异常时,事务不回滚,产生其他异常时事务回滚。没有默认值。表示任何异常都回滚。
  56. 测试:no-rollback-for="java.lang.ArithmeticException",遇到算数异常不回滚
  57. -->
  58. <tx:attributes>
  59. <tx:method name="*" propagation="REQUIRED" read-only="false"/>
  60. <tx:method name="find*" propagation="SUPPORTS" read-only="true"></tx:method>
  61. </tx:attributes>
  62. </tx:advice>
  63. <!-- 三:配置aop-->
  64. <aop:config>
  65. <!-- 配置切入点表达式-->
  66. <aop:pointcut id="pc" expression="execution(* com.it.service..*.*(..))"></aop:pointcut>
  67. <!--建立切入点表达式和事务通知的对应关系 -->
  68. <aop:advisor advice-ref="txAdvice" pointcut-ref="pc"></aop:advisor>
  69. </aop:config>
  70. </beans>

注解

配置AccountDaoImpl.java

  1. @Repository
  2. public class AccountDaoImpl extends JdbcDaoSupport implements AccountDao {
  3. @Autowired
  4. public void setDi(DataSource dataSource){
  5. super.setDataSource(dataSource);
  6. }
  7. }

配置AccountServiceImpl.java

  1. @Service
  2. @Transactional(readOnly = true)
  3. public class AccountServiceImpl implements AccountService {
  4. @Autowired
  5. private AccountDao accountDao;
  6. public Account findAccountById(Integer accountId) {
  7. return accountDao.findAccountById(accountId);
  8. }
  9. @Transactional(readOnly = false,propagation = Propagation.REQUIRED)
  10. public void transfer( String sourceName, String targetName, Float money) {
  11. System.out.println("transfer....");
  12. //2.1根据名称查询转出账户
  13. Account source = accountDao.findAccountByName(sourceName);
  14. //2.2根据名称查询转入账户
  15. Account target = accountDao.findAccountByName(targetName);
  16. //2.3转出账户减钱
  17. source.setMoney(source.getMoney() - money);
  18. //2.4转入账户加钱
  19. target.setMoney(target.getMoney() + money);
  20. //2.5更新转出账户
  21. accountDao.updateAccount(source);
  22. int i=1/0;
  23. //2.6更新转入账户
  24. accountDao.updateAccount(target);
  25. }
  26. }

注意:方法级别的事务会覆盖类级别的事务

配置applicationContext.xml

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:context="http://www.springframework.org/schema/context"
  4. xmlns:aop="http://www.springframework.org/schema/aop"
  5. xmlns:tx="http://www.springframework.org/schema/tx"
  6. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  7. xsi:schemaLocation="http://www.springframework.org/schema/beans
  8. http://www.springframework.org/schema/beans/spring-beans.xsd
  9. http://www.springframework.org/schema/context
  10. http://www.springframework.org/schema/context/spring-context.xsd
  11. http://www.springframework.org/schema/aop
  12. http://www.springframework.org/schema/aop/spring-aop.xsd
  13. http://www.springframework.org/schema/tx
  14. http://www.springframework.org/schema/tx/spring-tx.xsd">
  15. <context:component-scan base-package="com.it"></context:component-scan>
  16. <!--配置JdbcTemplate-->
  17. <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
  18. <property name="dataSource" ref="dataSource"></property>
  19. </bean>
  20. <!-- 配置数据源-->
  21. <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
  22. <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
  23. <property name="url" value="jdbc:mysql://localhost:3306/itcastspring"></property>
  24. <property name="username" value="root"></property>
  25. <property name="password" value="root"></property>
  26. </bean>
  27. <!-- spring中基于XML的声明式事务控制配置步骤
  28. 1、配置事务管理器
  29. 2、配置事务的通知,通过注解的方式
  30. -->
  31. <!-- 配置事务管理器 -->
  32. <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
  33. <property name="dataSource" ref="dataSource"></property>
  34. </bean>
  35. <tx:annotation-driven transaction-manager="transactionManager"></tx:annotation-driven>
  36. </beans>

Spring整体的总结:

总结:

1:IOC DI(xml和注解)

2:AOP(5种通知)(xml和注解)

3:声明式事务处理(xml和注解)

  • * DBUtils(第三方提供的)
  • * JDBCTemplate(是spring提供的)

4:spring3的新特性(纯注解开发)

  • @Configuration
  • @ConnectionScan
  • @Import
  • @Bean

自己创建的对象:使用注解

第三方创建的对象(数据源…):使用配置文件

posted @ 2019-07-03 00:40  不穿格子衫的徍爺  阅读(112)  评论(0编辑  收藏  举报