摘要
spring中的JdbcTemplate JdbcTemplate的作用: 它就是用于和数据库交互的,实现对表的CRUD操作 如何创建该对象: 对象中的常用方法:
作业: spring基于AOP的事务控制
spring中的事务控制 基于XML的 基于注解的
project:day04_01jdbctemplate
概述和入门
导入依赖
<packaging>jar
</packaging>
<dependencies>
<dependency>
<groupId>org.springframework
</groupId>
<artifactId>spring-context
</artifactId>
<version>5.0.2.RELEASE
</version>
</dependency>
<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>mysql
</groupId>
<artifactId>mysql-connector-java
</artifactId>
<version>5.1.6
</version>
</dependency>
</dependencies>
建立实体类domain.Account
public class Account implements Serializable {
private Integer id
;
private String name
;
private Float 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 Float
getMoney() {
return money
;
}
public void setMoney(Float money
) {
this.money
= money
;
}
@Override
public String
toString() {
return "Account{" +
"id=" + id
+
", name='" + name
+ '\'' +
", money=" + money
+
'}';
}
}
创建JdbcTemplateDemo1
package com
.itheima
.jdbctemplate
;
import org
.springframework
.jdbc
.core
.JdbcTemplate
;
import org
.springframework
.jdbc
.datasource
.DriverManagerDataSource
;
public class JdbcTemplateDemo1 {
public static void main(String
[] args
) {
DriverManagerDataSource ds
= new DriverManagerDataSource();
ds
.setDriverClassName("com.mysql.jdbc.Driver");
ds
.setUrl("jdbc:mysql://localhost:3306/eesy");
ds
.setUsername("root");
ds
.setPassword("admin");
JdbcTemplate jt
= new JdbcTemplate();
jt
.setDataSource(ds
);
jt
.execute("insert into account (name, money) values ('ddd', 1000)");
}
}
JdbcTemplate在Spring的ioc中的使用
创建bean.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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"></property>
</bean>
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
<property name="url" value="jdbc:mysql://localhost:3306/eesy"></property>
<property name="username" value="root"></property>
<property name="password" value="admin"></property>
</bean>
</beans>
创建JdbcTemplateDemo2
package com
.itheima
.jdbctemplate
;
import org
.springframework
.context
.ApplicationContext
;
import org
.springframework
.context
.support
.ClassPathXmlApplicationContext
;
import org
.springframework
.jdbc
.core
.JdbcTemplate
;
import org
.springframework
.jdbc
.datasource
.DriverManagerDataSource
;
public class JdbcTemplateDemo2 {
public static void main(String
[] args
) {
ApplicationContext ac
= new ClassPathXmlApplicationContext("bean.xml");
JdbcTemplate jdbcTemplate
= ac
.getBean("jdbcTemplate", JdbcTemplate
.class);
jdbcTemplate
.execute("insert into account (name, money) values ('fff', 1000)");
}
}
CRUD
创建 JdbcTemplateDemo3
保存
package com
.itheima
.jdbctemplate
;
import org
.springframework
.context
.ApplicationContext
;
import org
.springframework
.context
.support
.ClassPathXmlApplicationContext
;
import org
.springframework
.jdbc
.core
.JdbcTemplate
;
public class JdbcTemplateDemo3 {
public static void main(String
[] args
) {
ApplicationContext ac
= new ClassPathXmlApplicationContext("bean.xml");
JdbcTemplate jdbcTemplate
= ac
.getBean("jdbcTemplate", JdbcTemplate
.class);
jdbcTemplate
.update("insert into account (name , money) values (?, ?)", "ggg", 1000f);
}
}
更新
package com
.itheima
.jdbctemplate
;
import org
.springframework
.context
.ApplicationContext
;
import org
.springframework
.context
.support
.ClassPathXmlApplicationContext
;
import org
.springframework
.jdbc
.core
.JdbcTemplate
;
public class JdbcTemplateDemo3 {
public static void main(String
[] args
) {
ApplicationContext ac
= new ClassPathXmlApplicationContext("bean.xml");
JdbcTemplate jdbcTemplate
= ac
.getBean("jdbcTemplate", JdbcTemplate
.class);
jdbcTemplate
.update("update account set name=?, money=? where id=?", "test", 2000, 7);
}
}
删除
package com
.itheima
.jdbctemplate
;
import org
.springframework
.context
.ApplicationContext
;
import org
.springframework
.context
.support
.ClassPathXmlApplicationContext
;
import org
.springframework
.jdbc
.core
.JdbcTemplate
;
public class JdbcTemplateDemo3 {
public static void main(String
[] args
) {
ApplicationContext ac
= new ClassPathXmlApplicationContext("bean.xml");
JdbcTemplate jdbcTemplate
= ac
.getBean("jdbcTemplate", JdbcTemplate
.class);
jdbcTemplate
.update("delete from account where id=?", 7);
}
}
查询所有
package com
.itheima
.jdbctemplate
;
import com
.itheima
.domain
.Account
;
import org
.springframework
.context
.ApplicationContext
;
import org
.springframework
.context
.support
.ClassPathXmlApplicationContext
;
import org
.springframework
.jdbc
.core
.BeanPropertyRowMapper
;
import org
.springframework
.jdbc
.core
.JdbcTemplate
;
import java
.util
.List
;
public class JdbcTemplateDemo3 {
public static void main(String
[] args
) {
ApplicationContext ac
= new ClassPathXmlApplicationContext("bean.xml");
JdbcTemplate jdbcTemplate
= ac
.getBean("jdbcTemplate", JdbcTemplate
.class);
List
<Account> accounts
= jdbcTemplate
.query("select * from account", new BeanPropertyRowMapper<Account>(Account
.class));
for (Account account
: accounts
) {
System
.out
.println(account
);
}
}
}
加上参数:
List
<Account> accounts
= jdbcTemplate
.query("select * from account where money > ?", new BeanPropertyRowMapper<Account>(Account
.class), 1000f);
for (Account account
: accounts
) {
System
.out
.println(account
);
}
查询一个
package com
.itheima
.jdbctemplate
;
import com
.itheima
.domain
.Account
;
import org
.springframework
.context
.ApplicationContext
;
import org
.springframework
.context
.support
.ClassPathXmlApplicationContext
;
import org
.springframework
.jdbc
.core
.BeanPropertyRowMapper
;
import org
.springframework
.jdbc
.core
.JdbcTemplate
;
import java
.util
.List
;
public class JdbcTemplateDemo3 {
public static void main(String
[] args
) {
ApplicationContext ac
= new ClassPathXmlApplicationContext("bean.xml");
JdbcTemplate jdbcTemplate
= ac
.getBean("jdbcTemplate", JdbcTemplate
.class);
List
<Account> accounts
= jdbcTemplate
.query("select * from account where id = ?", new BeanPropertyRowMapper<Account>(Account
.class), 1);
System
.out
.println(accounts
.isEmpty()?"没有内容":accounts
.get(0));
}
}
查询返回一行一列
package com
.itheima
.jdbctemplate
;
import com
.itheima
.domain
.Account
;
import org
.springframework
.context
.ApplicationContext
;
import org
.springframework
.context
.support
.ClassPathXmlApplicationContext
;
import org
.springframework
.jdbc
.core
.BeanPropertyRowMapper
;
import org
.springframework
.jdbc
.core
.JdbcTemplate
;
import java
.util
.List
;
public class JdbcTemplateDemo3 {
public static void main(String
[] args
) {
ApplicationContext ac
= new ClassPathXmlApplicationContext("bean.xml");
JdbcTemplate jdbcTemplate
= ac
.getBean("jdbcTemplate", JdbcTemplate
.class);
Long count
= jdbcTemplate
.queryForObject("select count(*) from account where money > ?", Long
.class, 1000f);
System
.out
.println(count
);
}
}
JdbcTemplate在Dao中的应用
创建dao.IAccountDao
package com
.itheima
.dao
;
import com
.itheima
.domain
.Account
;
public interface IAccountDao {
Account
findAccountById(Integer accountId
);
Account
findAccountByName(String accountName
);
void updateAccount(Account account
);
}
创建dao.impl.AccountDaoImpl
package com
.itheima
.dao
.impl
;
import com
.itheima
.dao
.IAccountDao
;
import com
.itheima
.domain
.Account
;
import org
.springframework
.jdbc
.core
.BeanPropertyRowMapper
;
import org
.springframework
.jdbc
.core
.JdbcTemplate
;
import java
.util
.List
;
public class AccountDaoImpl implements IAccountDao {
private JdbcTemplate jdbcTemplate
;
public Account
findAccountById(Integer accountId
) {
List
<Account> accounts
= jdbcTemplate
.query("select * from account where id = ?",
new BeanPropertyRowMapper<Account>(Account
.class), accountId
);
return accounts
.isEmpty()?null
:accounts
.get(0);
}
public Account
findAccountByName(String accountName
) {
List
<Account> accounts
= jdbcTemplate
.query("select * from account where name = ?",
new BeanPropertyRowMapper<Account>(Account
.class), accountName
);
if (accounts
.isEmpty())
return null
;
if (accounts
.size() > 1)
throw new RuntimeException("结果集不唯一");
return accounts
.get(0);
}
public void updateAccount(Account account
) {
jdbcTemplate
.update("update account set name = ?, money = ? where id = ?", account
.getName(), account
.getMoney(), account
.getId());
}
}
bean.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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="accountDao" class="com.itheima.dao.impl.AccountDaoImpl">
<property name="jdbcTemplate" ref="jdbcTemplate"></property>
</bean>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"></property>
</bean>
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
<property name="url" value="jdbc:mysql://localhost:3306/eesy"></property>
<property name="username" value="root"></property>
<property name="password" value="admin"></property>
</bean>
</beans>
创建JdbcTemplateDemo4测试
package com
.itheima
.jdbctemplate
;
import com
.itheima
.dao
.IAccountDao
;
import com
.itheima
.domain
.Account
;
import org
.springframework
.context
.ApplicationContext
;
import org
.springframework
.context
.support
.ClassPathXmlApplicationContext
;
import org
.springframework
.jdbc
.core
.JdbcTemplate
;
public class JdbcTemplateDemo4 {
public static void main(String
[] args
) {
ApplicationContext ac
= new ClassPathXmlApplicationContext("bean.xml");
IAccountDao accountDao
= ac
.getBean("accountDao", IAccountDao
.class);
Account account
= accountDao
.findAccountById(1);
System
.out
.println(account
);
account
.setMoney(10000f);
accountDao
.updateAccount(account
);
}
}
创建JdbcDaoSupport抽取Dao中重复代码
package com
.itheima
.dao
.impl
;
import org
.springframework
.jdbc
.core
.JdbcTemplate
;
import javax
.sql
.DataSource
;
public class JdbcDaoSupport {
private JdbcTemplate jdbcTemplate
;
public void setJdbcTemplate(JdbcTemplate jdbcTemplate
) {
this.jdbcTemplate
= jdbcTemplate
;
}
public JdbcTemplate
getJdbcTemplate() {
return jdbcTemplate
;
}
public void setDataSource(DataSource dataSource
) {
if (jdbcTemplate
== null
)
jdbcTemplate
= createJdbcTemplate(dataSource
);
}
private JdbcTemplate
createJdbcTemplate(DataSource dataSource
) {
return new JdbcTemplate(dataSource
);
}
}
在AccountDaoImpl中继承
package com
.itheima
.dao
.impl
;
import com
.itheima
.dao
.IAccountDao
;
import com
.itheima
.domain
.Account
;
import org
.springframework
.jdbc
.core
.BeanPropertyRowMapper
;
import org
.springframework
.jdbc
.core
.JdbcTemplate
;
import java
.util
.List
;
public class AccountDaoImpl extends JdbcDaoSupport implements IAccountDao {
public Account
findAccountById(Integer accountId
) {
List
<Account> accounts
= super.getJdbcTemplate().query("select * from account where id = ?",
new BeanPropertyRowMapper<Account>(Account
.class), accountId
);
return accounts
.isEmpty()?null
:accounts
.get(0);
}
public Account
findAccountByName(String accountName
) {
List
<Account> accounts
= super.getJdbcTemplate().query("select * from account where name = ?",
new BeanPropertyRowMapper<Account>(Account
.class), accountName
);
if (accounts
.isEmpty())
return null
;
if (accounts
.size() > 1)
throw new RuntimeException("结果集不唯一");
return accounts
.get(0);
}
public void updateAccount(Account account
) {
super.getJdbcTemplate().update("update account set name = ?, money = ? where id = ?", account
.getName(), account
.getMoney(), account
.getId());
}
}
在bean.xml中注入dataSource
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="accountDao" class="com.itheima.dao.impl.AccountDaoImpl">
<property name="dataSource" ref="dataSource"></property>
</bean>
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
<property name="url" value="jdbc:mysql://localhost:3306/eesy"></property>
<property name="username" value="root"></property>
<property name="password" value="admin"></property>
</bean>
</beans>
JdbcSupport在Spring中已存在
只需要在AccountDaoImpl中导入即可:
使用继承后,不能用注解配置了。
project:day04_02account_aoptx_xml
基于XML的AOP事务控制
复制day03_01Account
删除factory包
修改bean.xml
修改aop的xml头部信息:
配置aop
<?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:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<bean id="accountService" class="com.itheima.service.impl.AccountServiceImpl">
<property name="accountDao" ref="accountDao"></property>
</bean>
<bean id="accountDao" class="com.itheima.dao.impl.AccountDaoImpl">
<property name="runner" ref="runner"></property>
<property name="connectionUtils" ref="connectionUtils"></property>
</bean>
<bean id="runner" class="org.apache.commons.dbutils.QueryRunner" scope="prototype"></bean>
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="com.mysql.jdbc.Driver"></property>
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/eesy"></property>
<property name="user" value="root"></property>
<property name="password" value="admin"></property>
</bean>
<bean id="connectionUtils" class="com.itheima.utils.ConnectionUtils">
<property name="dataSource" ref="dataSource"></property>
</bean>
<bean id="txManager" class="com.itheima.utils.TransactionManager">
<property name="connectionUtils" ref="connectionUtils"></property>
</bean>
<aop:config>
<aop:pointcut id="pt1" expression="execution(* com.itheima.service.impl.*.*(..))"></aop:pointcut>
<aop:aspect id="txAdvice" ref="txManager">
<aop:before method="beginTransaction" pointcut-ref="pt1"></aop:before>
<aop:after-returning method="commit" pointcut-ref="pt1"></aop:after-returning>
<aop:after-throwing method="rollback" pointcut-ref="pt1"></aop:after-throwing>
<aop:after method="release" pointcut-ref="pt1"></aop:after>
</aop:aspect>
</aop:config>
</beans>
project:day04_03account_aoptx_anno
基于注解的AOP事务控制
复制day04_02account_aoptx_xml
改造ioc,修改bean.xml
1. 导入context
2. 配置spring创建容器时要扫描的包
<context:component-scan base-package="com.itheima"></context:component-scan>
3. 配置Service
4. 配置Dao
5. 配置Connection的工具类 ConnectionUtils
6. 配置事务管理器、配置aop
package com
.itheima
.utils
;
import org
.aspectj
.lang
.annotation
.*
;
import org
.springframework
.beans
.factory
.annotation
.Autowired
;
import org
.springframework
.stereotype
.Component
;
import java
.sql
.SQLException
;
@Component("txManager")
@Aspect
public class TransactionManager {
@Autowired
private ConnectionUtils connectionUtils
;
@Pointcut("execution( * com.itheima.service.impl.*.*(..))")
public void pt1(){};
@Before("pt1()")
public void beginTransaction() {
try {
connectionUtils
.getThreadConnection().setAutoCommit(false);
} catch (Exception e
) {
throw new RuntimeException(e
);
}
}
@AfterReturning("pt1()")
public void commit() {
try {
connectionUtils
.getThreadConnection().commit();
} catch (Exception e
) {
throw new RuntimeException(e
);
}
}
@AfterThrowing("pt1()")
public void rollback() {
try {
connectionUtils
.getThreadConnection().rollback();
} catch (Exception e
) {
throw new RuntimeException(e
);
}
}
@After("pt1()")
public void release() {
try {
connectionUtils
.getThreadConnection().close();
connectionUtils
.removeConnection();
} catch (Exception e
) {
throw new RuntimeException(e
);
}
}
}
7. 开启spring对注解AOP的支持
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
8. bean.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:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="com.itheima"></context:component-scan>
<bean id="runner" class="org.apache.commons.dbutils.QueryRunner" scope="prototype"></bean>
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="com.mysql.jdbc.Driver"></property>
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/eesy"></property>
<property name="user" value="root"></property>
<property name="password" value="admin"></property>
</bean>
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
</beans>
执行测试类产生异常
是因为最终通知和异常通知的顺序有问题。 只能使用环绕通知
使用环绕通知
@Around("pt1()")
public Object
aroundAdvice(ProceedingJoinPoint pjp
){
Object rtValue
= null
;
try {
Object
[] args
= pjp
.getArgs();
this.beginTransaction();
rtValue
= pjp
.proceed(args
);
this.commit();
return rtValue
;
}catch (Throwable e
){
this.rollback();
throw new RuntimeException(e
);
}finally {
this.release();
}
}
project:day04_04tx
Spring事务控制
1. 配置依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0
</modelVersion>
<groupId>com.itheima
</groupId>
<artifactId>day04_04tx
</artifactId>
<version>1.0-SNAPSHOT
</version>
<packaging>jar
</packaging>
<dependencies>
<dependency>
<groupId>org.springframework
</groupId>
<artifactId>spring-context
</artifactId>
<version>5.0.2.RELEASE
</version>
</dependency>
<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>mysql
</groupId>
<artifactId>mysql-connector-java
</artifactId>
<version>5.1.6
</version>
</dependency>
<dependency>
<groupId>org.aspectj
</groupId>
<artifactId>aspectjweaver
</artifactId>
<version>1.8.7
</version>
</dependency>
</dependencies>
</project>
2. 拷贝day04_01jdbctemplate
删除 AccountDaoImpl2 JdbcDaoSupport.java
3. 创建IAccountService
4. 创建AccountServiceImpl
package com
.itheima
.service
.impl
;
import com
.itheima
.dao
.IAccountDao
;
import com
.itheima
.domain
.Account
;
import com
.itheima
.service
.IAccountService
;
import org
.springframework
.stereotype
.Service
;
public class AccountServiceImpl implements IAccountService{
private IAccountDao accountDao
;
public void setAccountDao(IAccountDao accountDao
) {
this.accountDao
= accountDao
;
}
@Override
public Account
findAccountById(Integer accountId
) {
return accountDao
.findAccountById(accountId
);
}
@Override
public void transfer(String sourceName
, String targetName
, Float money
) {
System
.out
.println("transfer....");
Account source
= accountDao
.findAccountByName(sourceName
);
Account target
= accountDao
.findAccountByName(targetName
);
source
.setMoney(source
.getMoney()-money
);
target
.setMoney(target
.getMoney()+money
);
accountDao
.updateAccount(source
);
int i
=1/0;
accountDao
.updateAccount(target
);
}
}
5. 创建AccountServiceTest
package com
.itheima
.test
;
import com
.itheima
.service
.IAccountService
;
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(locations
= "classpath:bean.xml")
public class AccountServiceTest {
@Autowired
private IAccountService as
;
@Test
public void testTransfer(){
as
.transfer("aaa","bbb",100f);
}
}
pom.xml需导入:
<dependency>
<groupId>junit
</groupId>
<artifactId>junit
</artifactId>
<version>4.12
</version>
</dependency>
<dependency>
<groupId>org.springframework
</groupId>
<artifactId>spring-test
</artifactId>
<version>5.0.2.RELEASE
</version>
</dependency>
6. 配置业务层
<bean id="accountService" class="com.itheima.service.impl.AccountServiceImpl">
<property name="accountDao" ref="accountDao"></property>
</bean>
此时无法实现事务控制
project:day04_05tx_xml
拷贝day04_04tx
基于xml的Spring事务管理
spring中基于XML的声明式事务控制配置步骤
1、配置事务管理器
2、配置事务的通知
此时我们需要导入事务的约束 tx名称空间和约束,同时也需要aop的
使用tx:advice标签配置事务通知
属性:
id:给事务通知起一个唯一标识
transaction-manager:给事务通知提供一个事务管理器引用
3、配置AOP中的通用切入点表达式
4、建立事务通知和切入点表达式的对应关系
5、配置事务的属性
是在事务的通知tx:advice标签的内部
1. 配置事务管理器
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
2. 配置事务的通知
导入事务的约束 tx名称空间和约束,同时也需要aop的
<tx:advice id="txAdvice" transaction-manager="transactionManager"></tx:advice>
3. 配置AOP中的通用切入点表达式
<aop:config>
<aop:pointcut id="pt1" expression="execution(* com.itheima.service.impl.*.*(..))"/>
</aop:config>
4. 建立事务通知和切入点表达式的对应关系
<aop:config>
<aop:pointcut id="pt1" expression="execution(* com.itheima.service.impl.*.*(..))"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="pt1"></aop:advisor>
</aop:config>
5. 配置事务的属性
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="*" propagation="REQUIRED" read-only="false"/>
<tx:method name="find*" propagation="SUPPORTS" read-only="true"></tx:method>
</tx:attributes>
</tx:advice>
bean.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: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.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<bean id="accountService" class="com.itheima.service.impl.AccountServiceImpl">
<property name="accountDao" ref="accountDao"></property>
</bean>
<bean id="accountDao" class="com.itheima.dao.impl.AccountDaoImpl">
<property name="dataSource" ref="dataSource"></property>
</bean>
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
<property name="url" value="jdbc:mysql://localhost:3306/eesy"></property>
<property name="username" value="root"></property>
<property name="password" value="admin"></property>
</bean>
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="*" propagation="REQUIRED" read-only="false"/>
<tx:method name="find*" propagation="SUPPORTS" read-only="true"></tx:method>
</tx:attributes>
</tx:advice>
<aop:config>
<aop:pointcut id="pt1" expression="execution(* com.itheima.service.impl.*.*(..))"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="pt1"></aop:advisor>
</aop:config>
</beans>
6. 测试
project:day04_06tx_anno
拷贝day04_05tx_xml
基于注解的Spring事务管理
修改bean.xml
导入context
配置业务层accountService
配置账户的持久层accountDao
配置JdbcTemplate
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"></property>
</bean>
配置spring创建容器时要扫描的包
<context:component-scan base-package="com.itheima"></context:component-scan>
步骤
spring中基于注解 的声明式事务控制配置步骤
1、配置事务管理器
2、开启spring对注解事务的支持
3、在需要事务支持的地方使用@Transactional注解
配置事务管理器
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
开启spring对注解事务的支持
<tx:annotation-driven transaction-manager="transactionManager"></tx:annotation-driven>
在需要事务支持的地方使用@Transactional注解
project:day04_07anno_tx_withoutxml
1. SpringConfiguration
package config
;
import org
.springframework
.context
.annotation
.ComponentScan
;
import org
.springframework
.context
.annotation
.Configuration
;
import org
.springframework
.context
.annotation
.Import
;
import org
.springframework
.context
.annotation
.PropertySource
;
import org
.springframework
.transaction
.annotation
.EnableTransactionManagement
;
@Configuration
@ComponentScan("com.itheima")
@Import({JdbcConfig
.class,TransactionConfig
.class})
@PropertySource("jdbcConfig.properties")
@EnableTransactionManagement
public class SpringConfiguration {
}
2. JdbcConfig
package config
;
import org
.springframework
.beans
.factory
.annotation
.Value
;
import org
.springframework
.context
.annotation
.Bean
;
import org
.springframework
.jdbc
.core
.JdbcTemplate
;
import org
.springframework
.jdbc
.datasource
.DriverManagerDataSource
;
import javax
.sql
.DataSource
;
public class JdbcConfig {
@Value("${jdbc.driver}")
private String driver
;
@Value("${jdbc.url}")
private String url
;
@Value("${jdbc.username}")
private String username
;
@Value("${jdbc.password}")
private String password
;
@Bean(name
="jdbcTemplate")
public JdbcTemplate
createJdbcTemplate(DataSource dataSource
){
return new JdbcTemplate(dataSource
);
}
@Bean(name
="dataSource")
public DataSource
createDataSource(){
DriverManagerDataSource ds
= new DriverManagerDataSource();
ds
.setDriverClassName(driver
);
ds
.setUrl(url
);
ds
.setUsername(username
);
ds
.setPassword(password
);
return ds
;
}
}
2. 创建jdbcConfig.properties
jdbc
.driver
=com
.mysql
.jdbc
.Driver
jdbc
.url
=jdbc
:mysql
://localhost
:3306/eesy
jdbc
.username
=root
jdbc
.password
=1234
3. 创建TransactionConfig.java
package config
;
import org
.springframework
.context
.annotation
.Bean
;
import org
.springframework
.jdbc
.datasource
.DataSourceTransactionManager
;
import org
.springframework
.transaction
.PlatformTransactionManager
;
import javax
.sql
.DataSource
;
public class TransactionConfig {
@Bean(name
="transactionManager")
public PlatformTransactionManager
createTransactionManager(DataSource dataSource
){
return new DataSourceTransactionManager(dataSource
);
}
}
4. 测试
package com
.itheima
.test
;
import com
.itheima
.service
.IAccountService
;
import config
.SpringConfiguration
;
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(classes
= SpringConfiguration
.class)
public class AccountServiceTest {
@Autowired
private IAccountService as
;
@Test
public void testTransfer(){
as
.transfer("aaa","bbb",100f);
}
}