Spring中的JdbcTemplate
pom.xml 添加坐標(biāo)
<dependencies>
<!--Spring核心容器-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.2.RELEASE</version>
</dependency>
<!--SpringJdbc-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.0.2.RELEASE</version>
</dependency>
<!--事務(wù)相關(guān)的-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>5.0.2.RELEASE</version>
</dependency>
<!--SpringAOP相關(guān)的坐標(biāo)-->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.7</version>
</dependency>
<!--數(shù)據(jù)庫驅(qū)動-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.6</version>
</dependency>
<!--druid連接池-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.0.14</version>
</dependency>
<!--dbutils連接池-->
<dependency>
<groupId>commons-dbutils</groupId>
<artifactId>commons-dbutils</artifactId>
<version>1.7</version>
</dependency>
<!--Spring整合單元測試-->
<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>
<scope>test</scope>
</dependency>
<!--連接池-->
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
<version>3.1.0</version>
</dependency>
</dependencies>
Account.java
package perm.coco.bean;
import java.io.Serializable;
public class Account implements Serializable {
private Integer id;
private String name;
private Double 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;
}
@Override
public String toString() {
return "Account{" +
"id=" + id +
", name='" + name + '\'' +
", money=" + money +
'}';
}
}
方式一 : 內(nèi)置JDBC
可以使用 xml方式 或 注解方式
AccountDaoImpl.java
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import perm.coco.bean.Account;
import perm.coco.dao.AccountDao;
/**
* Spring 內(nèi)置連接池
*/
public class AccountDaoImpl implements AccountDao {
/**
* 保存賬戶
* @param account
*/
@Override
public void save(Account account) {
//1.創(chuàng)建連接池(Spring內(nèi)置的)
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl("jdbc:mysql:///spring");
dataSource.setUsername("root");
dataSource.setPassword("root");
//1.創(chuàng)建JDBCTemplate對象
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
//操作數(shù)據(jù)庫
String sql = "insert into account (id,name,money) values(?,?,?)";
jdbcTemplate.update(sql, account.getId(), account.getName(), account.getMoney());
}
}
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<!--開啟包掃描-->
<context:component-scan base-package="perm.coco"></context:component-scan>
<!--注冊AccountDao-->
<bean id="accountDao01" class="perm.coco.dao.Impl.AccountDaoImpl"></bean>
</beans>
Test.java
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;
import perm.coco.bean.Account;
import perm.coco.dao.AccountDao;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(value = "classpath:applicationContext.xml")
public class AppTest {
//注入AccountDao
@Autowired
private AccountDao accountDao;
@Test
public void fun01() {
Account account = new Account();
account.setName("coco1");
account.setMoney(1002.0);
accountDao.save(account);
}
}
方式二: 繼承 JdbcDaoSupport
只能使用xml方式裹虫,注解用不了
AccountDaoImpl02.java
import org.springframework.jdbc.core.support.JdbcDaoSupport;
import perm.coco.bean.Account;
import perm.coco.dao.AccountDao;
/**
* 繼承JdbcSuport
*/
public class AccountDaoImpl02 extends JdbcDaoSupport implements AccountDao {
/**
* 內(nèi)置連接池
* 保存賬戶
* @param account
*/
@Override
public void save(Account account) {
//操作數(shù)據(jù)庫
String sql = "insert into account (id,name,money) values(?,?,?)";
getJdbcTemplate().update(sql, account.getId(), account.getName(), account.getMoney());
}
}
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<!--開啟包掃描-->
<context:component-scan base-package="perm.coco"></context:component-scan>
<!--使用JdbcDaoSupport,必須要注入dataSource
父類里面需要這個屬性幔虏,在注入的時候,會創(chuàng)建一個JdbcTemplate對象
就可以通過 getJdbcTemplate()來獲取直接使用了-->
<bean id="accountDao02" class="perm.coco.dao.Impl.AccountDaoImpl02">
<!--注入dataSource-->
<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:///spring"></property>
<property name="username" value="root"></property>
<property name="password" value="root"></property>
</bean>
</beans>
Test.java
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;
import perm.coco.bean.Account;
import perm.coco.dao.AccountDao;
import javax.annotation.Resource;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(value = "classpath:applicationContext.xml")
public class AppTest {
//注入AccountDao
@Resource(name = "accountDao02")
private AccountDao accountDao;
@Test
public void fun01() {
Account account = new Account();
account.setName("coco1");
account.setMoney(1002.0);
accountDao.save(account);
}
}
兩種方式比較
第一種在Dao類中定義JdbcTemplate的方式瘪吏,適用于所有配置方式(xml和注解都可以)
第二種讓Dao繼承JdbcDaoSupport的方式绊寻,只能用于基于XML的方式晒屎,注解用不了.
Spring 配置第三方連接池
c3p0
操作步驟:
- 在pom文件中添加c3p0坐標(biāo)
- 在配置文件里面配置 c3p0
pom.xml
<dependency>
<groupId>c3p0</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.1.2</version>
</dependency>
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<!--開啟包掃描-->
<context:component-scan base-package="perm.coco"></context:component-scan>
<!--注冊 c3p0 連接池-->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="com.mysql.jdbc.Driver"></property>
<property name="jdbcUrl" value="jdbc:mysql:///spring"></property>
<property name="user" value="root"></property>
<property name="password" value="root"></property>
</bean>
<!--注冊JdbcTemplate-->
<bean id="JdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<!--注入dataSource-->
<property name="dataSource" ref="dataSource"></property>
</bean>
</beans>
AccountDaoImpl.java
package perm.coco.dao.Impl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;
import perm.coco.bean.Account;
import perm.coco.dao.AccountDao;
/**
* c3p0 連接池
*/
@Repository("accountDao")
public class AccountDaoImpl implements AccountDao {
@Autowired
private JdbcTemplate jdbcTemplate;
/**
* 保存賬戶
* @param account
*/
@Override
public void save(Account account) {
String sql = "insert into account (id,name,money) values (?,?,?) ";
jdbcTemplate.update(sql, account.getId(), account.getName(), account.getMoney());
}
}
Test.java
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;
import perm.coco.bean.Account;
import perm.coco.dao.AccountDao;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(value = "classpath:applicationContext.xml")
public class AppTest {
@Autowired
private AccountDao accountDao;
@Test
public void fun01() {
Account account = new Account();
account.setName("hahha");
account.setMoney(1000.0);
accountDao.save(account);
}
}
druid
pom.xml
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.10</version>
</dependency>
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<!--開啟包掃描-->
<context:component-scan base-package="perm.coco"></context:component-scan>
<!--注冊 druid 連接池-->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
<property name="url" value="jdbc:mysql:///spring"></property>
<property name="username" value="root"></property>
<property name="password" value="root"></property>
</bean>
<!--注冊JdbcTemplate-->
<bean id="JdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<!--注入dataSource-->
<property name="dataSource" ref="dataSource"></property>
</bean>
</beans>
DBCP
HikariCP
pom.xml
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
<version>3.1.0</version>
</dependency>
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
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/context http://www.springframework.org/schema/context/spring-context.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">
<!--開啟包掃描-->
<context:component-scan base-package="perm.coco"></context:component-scan>
<!--注冊 hikariCP 連接池-->
<bean id="dataSource" class="com.zaxxer.hikari.HikariDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
<property name="jdbcUrl" value="jdbc:mysql:///spring"></property>
<property name="username" value="root"></property>
<property name="password" value="root"></property>
</bean>
<!-- 注冊JdbcTemplate-->
<bean id="dbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<!--注入dataSource-->
<property name="dataSource" ref="dataSource"></property>
</bean>
</beans>
Spring引入 Properties配置文件
-
步驟
1.定義jdbc.properties文件
2.在spring核心配置文件里面引入配置文件
3.根據(jù)key獲得值
jdbc.properties
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/spring
jdbc.username=root
jdbc.password=root
applicationContext.xml 頁面使用
- 引入配置文件方式一(不推薦使用)
<!-- 引入properties配置文件:方式一 (繁瑣不推薦使用) -->
<bean id="properties" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="classpath:jdbc.properties" />
</bean>
- 引入配置文件方式二
<!-- 引入properties配置文件:方式二 (簡單推薦使用) -->
<!--properties配置文件中的key一定要是帶點分隔的佑附。例如jdbc.url-->
<context:property-placeholder location="classpath:jdbc.properties" />
- bean標(biāo)簽中引用配置文件內(nèi)容
<!-- hikariCP 連接池 -->
<bean id="dataSource" class="com.zaxxer.hikari.HikariDataSource">
<property name="jdbcUrl" value="${jdbc.url}" />
<property name="driverClassName" value="${jdbc.driver}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</bean>
注意:在使用
<context:property-placeholder/>
標(biāo)簽時搞乏,properties配置文件中的key一定要是帶點分隔的。例如jdbc.url
Spring管理事物
簡介
? 由于Spring對持久層的很多框架都有支持 眠屎, Hibernate 剔交、 jdbc 、 MyBatis 由于使用的框架不同改衩,所以使用事務(wù)管理操作API 也不盡相同岖常。 為了規(guī)范這些操作, Spring統(tǒng)一定義一個事務(wù)的規(guī)范 葫督,這其實是一個接口 竭鞍。這個接口的名稱 : PlatformTrasactionManager.并且它對已經(jīng)做好的框架都有支持.
? 如果dao層使用的是JDBC 或者mybatis,那么 可以使用DataSourceTransactionManager 來處理事務(wù)
? 如果dao層使用的是 Hibernate, 那么可以使用HibernateTransactionManager 來處理事務(wù)
事務(wù)特性
- 原子型:事務(wù)是不可分割的工作單位,事務(wù)的操作要么都發(fā)生橄镜,要么都不發(fā)生
- 一致性:事務(wù)前后數(shù)據(jù)的完整性必須保持一致
- 隔離性:多個用戶并發(fā)訪問數(shù)據(jù)庫時偎快,一個用戶的事務(wù)不能被其他用戶的事務(wù)所干擾,多個并發(fā)事務(wù)之間數(shù)據(jù)要互相隔離
- 持久性:一個事務(wù)一旦被提交洽胶,它對數(shù)據(jù)庫中數(shù)據(jù)的改變是永久性的晒夹。即使數(shù)據(jù)庫發(fā)送故障也不應(yīng)該對其有任何影響
事務(wù)的 API
聲明事務(wù)管理機制(3個核心接口對象)
- PlatformTransactionManager 事務(wù)管理器
- commit 提交事務(wù)
- rollback 回滾
- getTransaction() 獲取事務(wù)狀態(tài)
- TransactionDefinition 事務(wù)定義信息
隔離級別
事務(wù)的傳播行為
超時信息
只讀
- TransactionStatus 事務(wù)具體運行狀態(tài)
注意:事務(wù)結(jié)束,必須通過 commit姊氓。rollback是作為標(biāo)記作為回滾丐怯。如果只是回滾,后面不操作翔横,數(shù)據(jù)庫與在關(guān)閉連接時,會自己commit
事務(wù)的傳播行為
事務(wù)的傳播行為的作用
? 我們一般都是將事務(wù)設(shè)置在Service層,那么當(dāng)我們調(diào)用Service層的一個方法的時候, 它能夠保證我們的這個方法中,執(zhí)行的所有的對數(shù)據(jù)庫的更新操作保持在一個事務(wù)中读跷, 在事務(wù)層里面調(diào)用的這些方法要么全部成功,要么全部失敗禾唁。
? 如果你的Service層的這個方法中效览,除了調(diào)用了Dao層的方法之外, 還調(diào)用了本類的其他的Service方法荡短,那么在調(diào)用其他的Service方法的時候钦铺, 我必須保證兩個service處在同一個事務(wù)中,確保事物的一致性肢预。
? 事務(wù)的傳播特性就是解決這個問題的矛洞。
事務(wù)的傳播行為的取值
保證在同一個事務(wù)里面:
-
PROPAGATION_REQUIRED:默認(rèn)值,也是最常用的場景.
如果當(dāng)前沒有事務(wù)烫映,就新建一個事務(wù)沼本,
如果已經(jīng)存在一個事務(wù)中,加入到這個事務(wù)中锭沟。 -
PROPAGATION_SUPPORTS:
如果當(dāng)前沒有事務(wù)抽兆,就以非事務(wù)方式執(zhí)行。
如果已經(jīng)存在一個事務(wù)中族淮,加入到這個事務(wù)中辫红。
-
PROPAGATION_MANDATORY
如果當(dāng)前沒有有事務(wù)凭涂,就拋出異常;
如果已經(jīng)存在一個事務(wù)中,加入到這個事務(wù)中贴妻。
保證不在同一個事物里:
-
PROPAGATION_REQUIRES_NEW
如果當(dāng)前有事務(wù)切油,把當(dāng)前事務(wù)掛起,創(chuàng)建新的事務(wù)但獨自執(zhí)行
-
PROPAGATION_NOT_SUPPORTED
如果當(dāng)前存在事務(wù),就把當(dāng)前事務(wù)掛起名惩。不創(chuàng)建事務(wù)
-
PROPAGATION_NEVER
如果當(dāng)前存在事務(wù)澎胡,拋出異常
-
PROPAGATION_NESTED
嵌套事務(wù) ,只對DataSourceTransactionManager有效 娩鹉,底層使用JDBC的SavePoint機制攻谁,允許在同一個事務(wù)設(shè)置保存點,回滾保存點
編程式事務(wù)管理
pom.xml
<dependencies>
<!--Spring核心容器-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.2.RELEASE</version>
</dependency>
<!--SpringJdbc-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.0.2.RELEASE</version>
</dependency>
<!--SpringAOP相關(guān)的坐標(biāo)-->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.7</version>
</dependency>
<!--事務(wù)相關(guān)的-->
<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>
<!--Spring整合單元測試-->
<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>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
<version>3.1.0</version>
</dependency>
</dependencies>
AccountServicesImpl.java
import com.zaxxer.hikari.HikariDataSource;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;
import perm.coco.dao.AccountDao;
import perm.coco.service.AccountService;
import sun.instrument.TransformerManager;
public class AccountServiceImpl implements AccountService {
//注入dao
private AccountDao accountDao;
public void setAccountDao(AccountDao accountDao) {
this.accountDao = accountDao;
}
//注入transactionTemplate
private TransactionTemplate transactionTemplate;
public void setTransactionTemplate(TransactionTemplate transactionTemplate) {
this.transactionTemplate = transactionTemplate;
}
@Override
public void transfer(String outUsername, String inUsername, Double money) {
transactionTemplate.execute(new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(TransactionStatus status) {
//轉(zhuǎn)出
accountDao.out(outUsername, money);
// int i = 1 / 0;
//轉(zhuǎn)入
accountDao.in(inUsername, money);
}
});
}
public void transfer02(String outUsername, String inUsername, Double money) {
//1.創(chuàng)建數(shù)據(jù)源
HikariDataSource dataSource = new HikariDataSource();
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/spring");
dataSource.setUsername("root");
dataSource.setPassword("root");
//1. 創(chuàng)建事務(wù)管理器
DataSourceTransactionManager transactionManager = new DataSourceTransactionManager(dataSource);
//創(chuàng)建事務(wù)管理器模板
TransactionTemplate transactionTemplate = new TransactionTemplate(transactionManager);
transactionTemplate.execute(new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(TransactionStatus status) {
//轉(zhuǎn)出
accountDao.out(outUsername, money);
// int i = 1 / 0;
//轉(zhuǎn)入
accountDao.in(inUsername, money);
}
});
}
}
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<!--注冊AccountDao-->
<bean id="accountDao" class="perm.coco.dao.Impl.AccountDaoImpl">
<!--注入JdbcTemplate-->
<property name="jdbcTemplate" ref="jdbcTemplate"></property>
</bean>
<!--注冊JdbcTemplate-->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<!--注入dataSource-->
<property name="dataSource" ref="dataSource"></property>
</bean>
<!--引入配置文件-->
<!--properties配置文件中的key一定要是帶點分隔的弯予。例如jdbc.url-->
<context:property-placeholder location="classpath:jdbc.properties"></context:property-placeholder>
<!--注冊dataSource-->
<bean id="dataSource" class="com.zaxxer.hikari.HikariDataSource">
<!--注入四個基本屬性-->
<property name="driverClassName" value="${jdbc.driver}"></property>
<property name="jdbcUrl" value="${jdbc.url}"></property>
<property name="username" value="${jdbc.username}"></property>
<property name="password" value="${jdbc.password}"></property>
</bean>
<!--編程式事務(wù)-->
<!--注冊事務(wù)管理器-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!--注入dataSource-->
<property name="dataSource" ref="dataSource"></property>
</bean>
<!--配置事物管理的模板-->
<bean id="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate">
<!--注入transactionManager-->
<property name="transactionManager" ref="transactionManager"></property>
</bean>
<!--注冊AccountService-->
<bean id="accountService" class="perm.coco.service.Impl.AccountServiceImpl">
<!--注入AccountDao-->
<property name="accountDao" ref="accountDao"></property>
<!--業(yè)務(wù)層注入事務(wù)模板-->
<property name="transactionTemplate" ref="transactionTemplate"></property>
</bean>
</beans>
聲明事務(wù)管理-基于TransactionProxyFactoryBean
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<!-- <!–開啟包掃描–>
<context:component-scan base-package="perm.coco"></context:component-scan>-->
<!--注冊AccountDao-->
<bean id="accountDao" class="perm.coco.dao.Impl.AccountDaoImpl">
<!--注入JdbcTemplate-->
<property name="jdbcTemplate" ref="jdbcTemplate"></property>
</bean>
<!--注冊AccountService-->
<bean id="accountService" class="perm.coco.service.Impl.AccountServiceImpl">
<!--注入AccountDao-->
<property name="accountDao" ref="accountDao"></property>
</bean>
<!--注冊JdbcTemplate-->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<!--注入dataSource-->
<property name="dataSource" ref="dataSource"></property>
</bean>
<!--引入配置文件-->
<!--properties配置文件中的key一定要是帶點分隔的戚宦。例如jdbc.url-->
<context:property-placeholder location="classpath:jdbc.properties"></context:property-placeholder>
<!--注冊dataSource-->
<bean id="dataSource" class="com.zaxxer.hikari.HikariDataSource">
<!--注入四個基本屬性-->
<property name="driverClassName" value="${jdbc.driver}"></property>
<property name="jdbcUrl" value="${jdbc.url}"></property>
<property name="username" value="${jdbc.username}"></property>
<property name="password" value="${jdbc.password}"></property>
</bean>
<!--注冊事務(wù)管理器-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!--注入dataSource-->
<property name="dataSource" ref="dataSource"></property>
</bean>
<!--配置業(yè)務(wù)層代理-->
<!--只能對一個類配置-->
<bean id="accountServiceProxy"
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<!--配置目標(biāo)對象-->
<property name="target" ref="accountService"></property>
<!--注入事務(wù)管理器transactionManager -->
<property name="transactionManager" ref="transactionManager"></property>
<!--注入事務(wù)屬性-->
<property name="transactionAttributes">
<props>
<!--prop的格式
key:方法名, *代表所有的方法名
propagation:事務(wù)的傳播行為
isolation:事務(wù)的隔離性
readonly:只讀
-Exception:發(fā)生哪些異常回滾事務(wù)
+Exception:發(fā)生哪些異常不回滾事務(wù)
-->
<prop key="*">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>
</beans>
AccountServicesImpl.java
import perm.coco.dao.AccountDao;
import perm.coco.service.AccountService;
public class AccountServiceImpl implements AccountService {
//注入dao
private AccountDao accountDao;
public void setAccountDao(AccountDao accountDao) {
this.accountDao = accountDao;
}
@Override
public void transfer(String outUsername, String inUsername, Double money) {
//轉(zhuǎn)出
accountDao.out(outUsername, money);
//int i = 1 / 0;
//轉(zhuǎn)入
accountDao.in(inUsername, money);
}
}
聲明事務(wù)管理-基于AspectJ(xml)
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
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/context http://www.springframework.org/schema/context/spring-context.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">
<!-- <!–開啟包掃描–>
<context:component-scan base-package="perm.coco"></context:component-scan>-->
<!--注冊AccountDao-->
<bean id="accountDao" class="perm.coco.dao.Impl.AccountDaoImpl">
<!--注入JdbcTemplate-->
<property name="jdbcTemplate" ref="jdbcTemplate"></property>
</bean>
<!--注冊AccountService-->
<bean id="accountService" class="perm.coco.service.Impl.AccountServiceImpl">
<!--注入AccountDao-->
<property name="accountDao" ref="accountDao"></property>
</bean>
<!--注冊JdbcTemplate-->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<!--注入dataSource-->
<property name="dataSource" ref="dataSource"></property>
</bean>
<!--引入配置文件-->
<!--properties配置文件中的key一定要是帶點分隔的锈嫩。例如jdbc.url-->
<context:property-placeholder location="classpath:jdbc.properties"></context:property-placeholder>
<!--注冊dataSource-->
<bean id="dataSource" class="com.zaxxer.hikari.HikariDataSource">
<!--注入四個基本屬性-->
<property name="driverClassName" value="${jdbc.driver}"></property>
<property name="jdbcUrl" value="${jdbc.url}"></property>
<property name="username" value="${jdbc.username}"></property>
<property name="password" value="${jdbc.password}"></property>
</bean>
<!--注冊事務(wù)管理器-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!--注入dataSource-->
<property name="dataSource" ref="dataSource"></property>
</bean>
<!--配置事務(wù)通知:事務(wù)增強-->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<!--配置事務(wù)的屬性-->
<tx:attributes>
<tx:method name="transfer" propagation="REQUIRED" isolation="SERIALIZABLE"/>
<tx:method name="updata*" propagation="REQUIRED" isolation="SERIALIZABLE"/>
</tx:attributes>
</tx:advice>
<!--配置切面-->
<aop:config>
<!--配置切入點-->
<aop:pointcut id="pointcut01" expression="execution(* perm.coco.service.*.*(..))"></aop:pointcut>
<!--配置切面-->
<aop:advisor advice-ref="txAdvice" pointcut-ref="pointcut01"></aop:advisor>
</aop:config>
</beans>
AccountServiceImpl.xml
import perm.coco.dao.AccountDao;
import perm.coco.service.AccountService;
public class AccountServiceImpl implements AccountService {
//注入dao
private AccountDao accountDao;
public void setAccountDao(AccountDao accountDao) {
this.accountDao = accountDao;
}
@Override
public void transfer(String outUsername, String inUsername, Double money) {
//轉(zhuǎn)出
accountDao.out(outUsername, money);
int i = 1 / 0;
//轉(zhuǎn)入
accountDao.in(inUsername, money);
}
}
聲明事務(wù)管理-注解
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context" xmlns: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/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
<!-- <!–開啟包掃描–>
<context:component-scan base-package="perm.coco"></context:component-scan>-->
<!--注冊AccountDao-->
<bean id="accountDao" class="perm.coco.dao.Impl.AccountDaoImpl">
<!--注入JdbcTemplate-->
<property name="jdbcTemplate" ref="jdbcTemplate"></property>
</bean>
<!--注冊AccountService-->
<bean id="accountService" class="perm.coco.service.Impl.AccountServiceImpl">
<!--注入AccountDao-->
<property name="accountDao" ref="accountDao"></property>
</bean>
<!--注冊JdbcTemplate-->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<!--注入dataSource-->
<property name="dataSource" ref="dataSource"></property>
</bean>
<!--引入配置文件-->
<!--properties配置文件中的key一定要是帶點分隔的受楼。例如jdbc.url-->
<context:property-placeholder location="classpath:jdbc.properties"></context:property-placeholder>
<!--注冊dataSource-->
<bean id="dataSource" class="com.zaxxer.hikari.HikariDataSource">
<!--注入四個基本屬性-->
<property name="driverClassName" value="${jdbc.driver}"></property>
<property name="jdbcUrl" value="${jdbc.url}"></property>
<property name="username" value="${jdbc.username}"></property>
<property name="password" value="${jdbc.password}"></property>
</bean>
<!--注冊事務(wù)管理器-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!--注入dataSource-->
<property name="dataSource" ref="dataSource"></property>
</bean>
<!--開啟事務(wù)注解-->
<tx:annotation-driven transaction-manager="transactionManager"></tx:annotation-driven>
</beans>
AccountServiceImpl.java
package perm.coco.service.Impl;
import org.springframework.transaction.annotation.Transactional;
import perm.coco.dao.AccountDao;
import perm.coco.service.AccountService;
@Transactional
public class AccountServiceImpl implements AccountService {
//注入dao
private AccountDao accountDao;
public void setAccountDao(AccountDao accountDao) {
this.accountDao = accountDao;
}
@Override
public void transfer(String outUsername, String inUsername, Double money) {
//轉(zhuǎn)出
accountDao.out(outUsername, money);
// int i = 1 / 0;
//轉(zhuǎn)入
accountDao.in(inUsername, money);
}
}