目录
Spring框架的JDBC模板技术
JDBC模板技术概述
JDBC的模板类的使用
使用Spring框架来管理模板类
Spring框架管理开源的连接池
Spring框架的JDBC模板的简单操作
模拟转账开发
Dao编写的方式(第二种方式)
Spring框架的事务管理
Spring框架的事务管理相关的类和API
Spring框架声明式事务管理
Spring框架的JDBC模板技术
JDBC模板技术概述
Spring框架中提供了很多持久层的模板类来简化编程,使用模板类编写程序会变的简单
- template 模板
- 都是Spring框架提供XxxTemplate
提供了JDBC模板,Spring框架提供的
- JdbcTemplate类,Connection 表示连接,管理事务 Statement ResultSet
如果不使用JdbcTemplate,想要实现增删改查需要以下步骤
- 加载驱动
- 通过Conection接口获取连接
- 编写sql语句
- 获取执行sql对象,Statment或者PreparedStatment(更推荐,是一种预编译SQL语句的方法,可以防止SQL注入问题,使用?作为占位符)
- 执行sql语句,返回查询结果,将结果封装在Result结果集中
- 释放资源
JDBC的模板类的使用
引入JdbcTemplate,JdbcTemplate接口会帮我们完成获取连接,执行sql语句并封装结果,释放资源
创建maven项目,引入坐标依赖
<dependencies><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.0.2.RELEASE</version></dependency><dependency><groupId>commons-logging</groupId><artifactId>commons-logging</artifactId><version>1.2</version></dependency><dependency><groupId>log4j</groupId><artifactId>log4j</artifactId><version>1.2.12</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-test</artifactId><version>5.0.2.RELEASE</version></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version></dependency><!-- AOP联盟 --><dependency><groupId>aopalliance</groupId><artifactId>aopalliance</artifactId><version>1.0</version></dependency><!-- Spring Aspects --><dependency><groupId>org.springframework</groupId><artifactId>spring-aspects</artifactId><version>5.0.2.RELEASE</version></dependency><!-- aspectj --><dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId><version>1.8.3</version></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.6</version></dependency><!--JDBC模板--><dependency><groupId>org.springframework</groupId><artifactId>spring-jdbc</artifactId><version>5.0.2.RELEASE</version></dependency><!-- 用于事务管理 --><dependency><groupId>org.springframework</groupId><artifactId>spring-tx</artifactId><version>5.0.2.RELEASE</version></dependency><dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.1.10</version></dependency>
</dependencies>
创建spring_db数据库
create database spring_db;
use spring_db;
create table account(id int primary key auto_increment,name varchar(40),money double
)character set utf8 collate utf8_general_ci;insert into account(name,money) values('aaa',1000);
insert into account(name,money) values('bbb',1000);
insert into account(name,money) values('ccc',1000);
数据库实体类
package com.qcby.demo4;public class Account {private Integer id;private String name;private Double money;public Account() {}public Account(Integer id, String name, Double money) {this.id = id;this.name = name;this.money = money;}public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public Double getMoney() {return money;}public void setMoney(Double money) {this.money = money;}@Overridepublic String toString() {return "Account{" +"id=" + id +", name='" + name + '\'' +", money=" + money +'}';}
}
测试类
package com.qcby.demo0401Test;import org.junit.Test;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.jdbc.core.JdbcTemplate;public class demo1 {/*** 使用new对象方式完成*/@Testpublic void run1(){//创建连接池对象,spring框架内置了连接池对象DriverManagerDataSource dataSource = new DriverManagerDataSource();//设置了4个参数dataSource.setDriverClassName("com.mysql.jdbc.Driver");dataSource.setUrl("jdbc:mysql://localhost:3306/spring_db");dataSource.setUsername("root");dataSource.setPassword("2020");//提供模板,创建对象JdbcTemplate template = new JdbcTemplate(dataSource);//完成数据的增删改查template.update("insert into account values (null,?,?)","熊大",1000);}
}
将连接池对象传入到JdbcTemplate中,直接调用JdbcTemplate中的方法即可完成操作
使用Spring框架来管理模板类
上面代码的JdbcTemplate是自己手动new出来的,我们可以把这些类交给Spring框架去管理。
在配置文件中使用Spring管理内置的连接池
<?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"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsd"><!-- demo1_1 --><!--配置连接池,使用的是Spring框架内置的连接池--><bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"><property name="driverClassName" value="com.mysql.jdbc.Driver"/><property name="url" value="jdbc:mysql://localhost:3306/spring_db"/><property name="username" value="root"/><property name="password" value="2020"/></bean><!--配置jdbc模板--><bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"><property name="dataSource" ref="dataSource"/></bean></beans>
编写测试方法
package com.qcby.demo0401Test;import com.qcby.demo4.Account;
import com.qcby.demo4.BeanMapper;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;import java.util.List;@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext_jdbc.xml")
public class demo1_1 {@Autowiredprivate JdbcTemplate jdbcTemplate;/*** 测试的方法*/@Testpublic void run1(){jdbcTemplate.update("insert into account values (null,?,?)","ccc",5000);}}
Spring框架管理开源的连接池
配置开源的连接池,使用Druid开源的连接池,引入坐标如下
<dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.1.10</version></dependency>
</dependencies>
创建属性文件jdbc.properties
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/spring_db
jdbc.username=root
jdbc.password=2020
完成核心配置
<?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"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsd"><!-- demo1_1 --><!--配置连接池,使用的是Spring框架内置的连接池--><!--<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">--><!--<property name="driverClassName" value="com.mysql.jdbc.Driver"/>--><!--<property name="url" value="jdbc:mysql://localhost:3306/spring_db"/>--><!--<property name="username" value="root"/>--><!--<property name="password" value="2020"/>--><!--</bean>--><!--使用开源连接池--><!--<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">--><!--<property name="driverClassName" value="com.mysql.jdbc.Driver"/>--><!--<property name="url" value="jdbc:mysql://localhost:3306/spring_db"/>--><!--<property name="username" value="root"/>--><!--<property name="password" value="2020"/>--><!--</bean>--><!--加载属性文件--><!--<bean id="placeholderConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">--><!--<property name="location" value="classpath:jdbc.properties"/>--><!--</bean>--><!--第二种写法:使用提供标签的方式--><context:property-placeholder location="jdbc.properties"/><!--加载属性的文件--><bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"><property name="driverClassName" value="${jdbc.driverClassName}"/><property name="url" value="${jdbc.url}"/><property name="username" value="${jdbc.username}"/><property name="password" value="${jdbc.password}"/></bean><!--配置jdbc模板--><bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"><property name="dataSource" ref="dataSource"/></bean></beans>
Spring框架的JDBC模板的简单操作
增删改查代码编写
package com.qcby.demo0401Test;import com.qcby.demo4.Account;
import com.qcby.demo4.BeanMapper;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;import java.util.List;@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext_jdbc.xml")
public class demo1_1 {@Autowiredprivate JdbcTemplate jdbcTemplate;/*** 测试的方法*/@Testpublic void run1(){jdbcTemplate.update("insert into account values (null,?,?)","ccc",5000);}/*** 修改*/@Testpublic void run2(){jdbcTemplate.update("update account set name = ?,money = ? where id = ?","小小怪下士",3000,7);}/*** 删除*/@Testpublic void run3(){jdbcTemplate.update("delete from account where id = ?",8);}/*** 通过id查询*/@Testpublic void run4(){Account account = jdbcTemplate.queryForObject("select * from account where id = ?", new BeanMapper(), 6);System.out.println(account);}/*** 查询所有的数据*/@Testpublic void run5(){List<Account> list = jdbcTemplate.query("select * from account",new BeanMapper());for(Account account:list){System.out.println(account);}}
}
模拟转账开发
引入依赖
<dependencies><!--spring的核心--><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.0.2.RELEASE</version></dependency><!--日志--><dependency><groupId>commons-logging</groupId><artifactId>commons-logging</artifactId><version>1.2</version></dependency><dependency><groupId>log4j</groupId><artifactId>log4j</artifactId><version>1.2.12</version></dependency><!--Junit测试--><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version><scope>test</scope></dependency><!--数据库连接池--><dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.1.10</version></dependency><!--Spring整合junit测试--><dependency><groupId>org.springframework</groupId><artifactId>spring-test</artifactId><version>5.0.2.RELEASE</version><scope>test</scope></dependency><!--mysql--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.6</version></dependency><!-- AOP联盟 --><dependency><groupId>aopalliance</groupId><artifactId>aopalliance</artifactId><version>1.0</version></dependency><!-- Spring Aspects --><dependency><groupId>org.springframework</groupId><artifactId>spring-aspects</artifactId><version>5.0.2.RELEASE</version></dependency><!-- aspectj --><dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId><version>1.8.3</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-jdbc</artifactId><version>5.0.2.RELEASE</version></dependency></dependencies>
service代码的编写
package com.qcby.service;import com.qcby.model.Account;public interface AccountService {public void updateSaveAll(Account account1, Account account2);
}
package com.qcby.service.Impl;import com.qcby.dao.AccountDao;
import com.qcby.model.Account;
import com.qcby.service.AccountService;public class AccountServiceImpl implements AccountService{private AccountDao accountDao;public void setAccountDao(AccountDao accountDao) {this.accountDao = accountDao;}@Overridepublic void updateSaveAll(Account account1, Account account2) {//try {//TxUtils.startTransaction();//保存账号1accountDao.updateSaveAll(account1);//显示除零错误//int a=1/0;//保存账户2accountDao.updateSaveAll(account2);//TxUtils.commit();//}catch (Exception e){//e.printStackTrace();//TxUtils.rollback();//}}
}
dao代码的编写
package com.qcby.dao;import com.qcby.model.Account;public interface AccountDao {public void updateSaveAll(Account account);
}
package com.qcby.dao.Impl;import com.qcby.dao.AccountDao;
import com.qcby.model.Account;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.support.JdbcDaoSupport;public class AccountDaoImpl implements AccountDao {private JdbcTemplate jdbcTemplate;public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {this.jdbcTemplate = jdbcTemplate;}//实现两个账户的转账@Overridepublic void updateSaveAll(Account account) {jdbcTemplate.update("update account set money = money + ? where name = ?",account.getMoney(),account.getName());}
}
配置文件代码编写
<?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"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsd"><bean id="accountService" class="com.qcby.service.Impl.AccountServiceImpl"><property name="accountDao" ref="accountDao"/></bean><bean id="accountDao" class="com.qcby.dao.Impl.AccountDaoImpl"><property name="jdbcTemplate" ref="jdbcTemplate"/></bean><!--配置Jdbc模板类--><bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"><property name="dataSource" ref="dataSource"/></bean><!--使用提供标签的方式--><context:property-placeholder location="classpath:jdbc.properties"/><bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"><property name="driverClassName" value="${jdbc.driverClassName}"/><property name="url" value="${jdbc.url}"/><property name="username" value="${jdbc.username}"/><property name="password" value="${jdbc.password}"/></bean></beans>
测试代码编写
package com.qcby.Test;import com.qcby.model.Account;
import com.qcby.service.AccountService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class Test01 {@Autowiredprivate AccountService accountService;@Testpublic void TestPay(){Account account1 = new Account(null,"aaa",-1000.00);Account account2 = new Account(null,"bbb",1000.00);accountService.updateSaveAll(account1,account2);}
}
Dao编写的方式(第二种方式)
package com.qcby.dao.Impl;import com.qcby.dao.AccountDao;
import com.qcby.model.Account;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.support.JdbcDaoSupport;public class AccountDaoImpl2 extends JdbcDaoSupport implements AccountDao {//实现两个账户的转账@Overridepublic void updateSaveAll(Account account) {this.getJdbcTemplate().update("update account set money = money + ? where name = ?",account.getMoney(),account.getName());}
}
<?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"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsd"><bean id="accountService" class="com.qcby.service.Impl.AccountServiceImpl"><property name="accountDao" ref="accountDao"/></bean><bean id="accountDao" class="com.qcby.dao.Impl.AccountDaoImpl2"><property name="dataSource" ref="dataSource"/></bean><!--<bean id="accountDao" class="com.qcby.dao.Impl.AccountDaoImpl"><property name="jdbcTemplate" ref="jdbcTemplate"/></bean>--><!--配置Jdbc模板类--><!--<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">--><!--<property name="dataSource" ref="dataSource"/>--><!--</bean>--><!-- 第二种写法:使用提供标签的方式--><context:property-placeholder location="classpath:jdbc.properties"/><!--加载属性的文件--><bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"><property name="driverClassName" value="${jdbc.driverClassName}"/><property name="url" value="${jdbc.url}"/><property name="username" value="${jdbc.username}"/><property name="password" value="${jdbc.password}"/></bean></beans>
package com.qcby.Test;import com.qcby.model.Account;
import com.qcby.service.AccountService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext_dao2.xml")
public class Test02 {@Autowiredprivate AccountService accountService;@Testpublic void TestPay(){Account account1 = new Account(null,"aaa",-1000.00);Account account2 = new Account(null,"bbb",1000.00);accountService.updateSaveAll(account1,account2);}
}
其余地方没有改变
Spring框架的事务管理
Spring框架的事务管理相关的类和API
PlatformTransactionManager接口
平台事务管理器。该接口有具体的实现类,根据不同的持久层框架,需要选择不同的实现类!相当于JdbcUtil工具类,这个接口中提供了提交事务,回滚事务等方法。
接口方法如下:
DataSourceTransactionManager 使用的Spring的JDBC模板或者MyBatis框架时选择
HibernateTransactionManager 使用的是Hibernate的框架时选择
方法 | 说明 |
TransactionStatus getTransaction(TransactionDefinition definition) | 获取事务状态信息 |
void commit(TransactionStatus status) | 提交事务 |
void rollback(TransactionStatus status) | 回滚事务 |
TransactionDefinition接口,事务定义信息接口
方法 | 说明 |
int getPropagationBehavior() | 获得事务的隔离级别 |
int getIsolationLevel(); | 获得事务的传播行为 |
int getTimeout(); | 获得超过时间 |
boolean isReadOnly(); | 是否为只读 |
事务的传播行为
- REQUIRED(默认):如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新的事务。
- SUPPORTS:如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务方式执行。
- MANDATORY:如果当前存在事务,则加入该事务;如果当前没有事务,则抛出异常。
- REQUIRES_NEW:总是创建一个新的事务,如果当前存在事务,则挂起当前事务。
- NOT_SUPPORTED:总是以非事务方式执行,如果当前存在事务,则挂起当前事务。
- NEVER:总是以非事务方式执行,如果当前存在事务,则抛出异常。
- NESTED:如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则表现同REQUIRED。
Spring框架声明式事务管理
配置文件方式
引入依赖
<dependencies><!--spring的核心--><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.0.2.RELEASE</version></dependency><!--日志--><dependency><groupId>commons-logging</groupId><artifactId>commons-logging</artifactId><version>1.2</version></dependency><dependency><groupId>log4j</groupId><artifactId>log4j</artifactId><version>1.2.12</version></dependency><!--Junit测试--><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version><scope>test</scope></dependency><!--数据库连接池--><dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.1.10</version></dependency><!--Spring整合junit测试--><dependency><groupId>org.springframework</groupId><artifactId>spring-test</artifactId><version>5.0.2.RELEASE</version><scope>test</scope></dependency><!--mysql--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.6</version></dependency><!-- AOP联盟 --><dependency><groupId>aopalliance</groupId><artifactId>aopalliance</artifactId><version>1.0</version></dependency><!-- Spring Aspects --><dependency><groupId>org.springframework</groupId><artifactId>spring-aspects</artifactId><version>5.0.2.RELEASE</version></dependency><!-- aspectj --><dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId><version>1.8.3</version></dependency><!-- JdbcTemplate模板 --><dependency><groupId>org.springframework</groupId><artifactId>spring-jdbc</artifactId><version>5.0.2.RELEASE</version></dependency><!-- 事务管理模块 --><dependency><groupId>org.springframework</groupId><artifactId>spring-tx</artifactId><version>5.0.2.RELEASE</version></dependency></dependencies>
编写实体类
package com.qcby.model;public class Account {private Integer id;private String name;private Double money;public Account() {}public Account(Integer id, String name, Double money) {this.id = id;this.name = name;this.money = money;}public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public Double getMoney() {return money;}public void setMoney(Double money) {this.money = money;}@Overridepublic String toString() {return "Account{" +"id=" + id +", name='" + name + '\'' +", money=" + money +'}';}
}
编写配置文件
对updateSaveAll进行增强,设置隔离级别为READ_COMMITTED读已提交
可以解决在转账过程中出错所造成的转账丢失问题
DEFAULT使用默认隔离级别
事务隔离级别
- READ_UNCOMMITTED(读未提交)
- READ_COMMITTED(读已提交)
- REPEATABLE_READ(可重复读)
- SERIALIZABLE(串行化)
<?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/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsdhttp://www.springframework.org/schema/txhttp://www.springframework.org/schema/tx/spring-tx.xsd"><!--使用提供标签的方式--><context:property-placeholder location="classpath:jdbc.properties"/><bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"><property name="driverClassName" value="${jdbc.driverClassName}"/><property name="url" value="${jdbc.url}"/><property name="username" value="${jdbc.username}"/><property name="password" value="${jdbc.password}"/></bean><!--配置平台事务管理器--><bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><property name="dataSource" ref="dataSource"/></bean><!--配置事务的通知(没有自己编写切面类,通知方法也不是自己编写,Spring框架提供的)--><tx:advice id="txAdvice" transaction-manager="transactionManager"><tx:attributes><!-- 对updateSaveAll进行增强,设置隔离级别,传播行为,超时的时间 --><tx:method name="updateSaveAll" isolation="DEFAULT" propagation="REQUIRED"/><tx:method name="find*" read-only="true"/></tx:attributes></tx:advice><!--配置AOP的增强--><aop:config><!--SPringle框架提供系统通知,使用advisor标签--><aop:advisor advice-ref="txAdvice" pointcut="execution(public * com.qcby.service.Impl.AccountServiceImpl.updateSaveAll(..))"/></aop:config><!-- 配置Jdbc模板类--><!--<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"><property name="dataSource" ref="dataSource"/></bean>--><!--配置service--><bean id="accountService" class="com.qcby.service.Impl.AccountServiceImpl"><property name="accountDao" ref="accountDao"/></bean><!--配置dao--><!--<bean id="accountDao" class="com.qcby.dao.Impl.AccountDaoImpl"><property name="jdbcTemplate" ref="jdbcTemplate"/></bean>--><bean id="accountDao" class="com.qcby.dao.Impl.AccountDaoImpl"><property name="dataSource" ref="dataSource"/></bean>
- name:切点方法名称
- isolation:事务的隔离级别
- propogation:事务的传播行为
- timeout:超时时间
- read-only:是否只读
持久层
package com.qcby.dao;import com.qcby.model.Account;public interface AccountDao {public void updateSaveAll(Account account);
}
package com.qcby.dao.Impl;import com.qcby.dao.AccountDao;
import com.qcby.model.Account;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.support.JdbcDaoSupport;/*public class AccountDaoImpl implements AccountDao {private JdbcTemplate jdbcTemplate;public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {this.jdbcTemplate = jdbcTemplate;}//实现两个账户的转账@Overridepublic void updateSaveAll(Account account) {jdbcTemplate.update("update account set money = money + ? where name = ?",account.getMoney(),account.getName());}
}*/public class AccountDaoImpl extends JdbcDaoSupport implements AccountDao {//实现两个账户的转账@Overridepublic void updateSaveAll(Account account) {this.getJdbcTemplate().update("update account set money = money + ? where name = ?",account.getMoney(),account.getName());}
}
业务层没有改动
配置文件+注解的方式
<?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/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsdhttp://www.springframework.org/schema/txhttp://www.springframework.org/schema/tx/spring-tx.xsd"><!--开启注解的扫描--><context:component-scan base-package="com.qcby"/><!--使用提供标签的方式--><context:property-placeholder location="classpath:jdbc.properties"/><!--加载属性的文件--><bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"><property name="driverClassName" value="${jdbc.driverClassName}"/><property name="url" value="${jdbc.url}"/><property name="username" value="${jdbc.username}"/><property name="password" value="${jdbc.password}"/></bean><!--配置平台事务管理器--><bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><property name="dataSource" ref="dataSource"/></bean><!-- 配置Jdbc模板类--><bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"><property name="dataSource" ref="dataSource"/></bean><!--开启事务注解的支持--><tx:annotation-driven transaction-manager="transactionManager"/></beans>
service代码
package com.qcby.service.Impl;import com.qcby.dao.AccountDao;
import com.qcby.model.Account;
import com.qcby.service.AccountService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;@Service
@Transactional(isolation = Isolation.DEFAULT)
public class AccountServiceImpl implements AccountService {@Autowiredprivate AccountDao accountDao;@Overridepublic void updateSaveAll(Account account1, Account account2) {//保存账号1accountDao.updateSaveAll(account1);//显示除零错误//int a=1/0;//保存账户2accountDao.updateSaveAll(account2);}
}
纯注解的方式
package com.qcby.utils;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.stereotype.Component;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;import javax.annotation.Resource;
import javax.sql.DataSource;/*** 配置类* @author Administrator*/
@Configuration
@ComponentScan("com.qcby")
@EnableTransactionManagement//开启事务注解
public class SpringConfig {@Bean(name="dataSource")public DataSource createDataSource() throws Exception {// 创建连接池对象,Spring框架内置了连接池对象DriverManagerDataSource dataSource = new DriverManagerDataSource();// 设置4个参数dataSource.setDriverClassName("com.mysql.jdbc.Driver");dataSource.setUrl("jdbc:mysql://localhost:3306/spring_db");dataSource.setUsername("root");dataSource.setPassword("2020");return dataSource;}@Resource(name="dataSource") // 不仅可以作用在属性上,也可以作用方法上。@Bean(name="jdbcTemplate") // 把JdbcTemplate保存到IOC容器中public JdbcTemplate createJdbcTemplate(DataSource dataSource) {JdbcTemplate template = new JdbcTemplate(dataSource);return template;}@Resource(name="dataSource")@Bean(name="transactionManager")public PlatformTransactionManager createTransactionManager(DataSource dataSource){DataSourceTransactionManager manager = new DataSourceTransactionManager(dataSource);return manager;}
}