筆記53-Spring jdbcTemplate&宣告式事務
文章目錄
JdbcTemplate基本使用
1. jdbcTemplate基本使用-概述(瞭解)
JdbcTemplate是spring框架中提供的一個物件, 是對原始繁瑣的jdbc API物件的簡單封裝. spring框架為我們提供了很多的操作模板類.例如: 操作關係型資料的JdbcTemplate和HibernateTemplate,操作nosql資料庫的RedisTemplate,操作訊息佇列的jmsTemplate等等.
2. JdbcTemplate基本使用-開發步驟(理解)
- 匯入spring-jdbc和spring-tx座標
- 建立資料庫表和實體
- 建立jdbcTemplate物件
- 執行資料庫操作
快速入門程式碼實現(應用)
匯入spring-jdbc和spring-tx座標
<?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.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.itheima</groupId>
<artifactId>itheima_spring_jdbc</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<name>itheima_spring_jdbc Maven Webapp</name>
<!-- FIXME change it to the project's website -->
<url>http://www.example.com</url>
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.32</version>
</dependency>
<dependency>
<groupId>c3p0</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.1.2</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.10</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.0.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>5.0.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.0.5.RELEASE</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.0.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>javax.servlet.jsp-api</artifactId>
<version>2.2.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.9.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.9.0</version>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.3</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.0.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>5.0.5.RELEASE</version>
</dependency>
</dependencies>
</project>
建立資料庫表和實體
package com.itheima.domain;
public class Account{
private String name;
private double money;
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{" +
"name='" + name + '\'' +
", money=" + money +
'}';
}
}
建立JdbcTemplate物件
執行資料庫操作
@Test
//測試JdbcTemplate開發步驟
public void test1() throws PropertyVetoException{
//建立資料來源物件
ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setDriverClass("com.mysql.jdbc.Driver");
dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/test");
dataSource.setUser("root");
dataSource.setPassword("1234");
JdbcTemplate jdbcTemplate = new JdbcTemplate();
//設定資料來源物件, 知道資料庫在哪
jdbcTemplate.setDataSource(dataSource);
//執行資料
int row = jdbcTemplate.update("insert into account values(?,?)","tom",5000);
System.out.println(row);
}
4.spring產生模板物件分析(理解)
我們可以將jdbcTemplate的建立權交給Spring, 將資料來源DataSource的建立權也交給Spring,在Spring容器內部將資料來源DataSource注入到JdbcTemplate模板物件中,然後通過Spring容器獲得JdbcTemplate物件來執行操作.
5. spring產生模板物件程式碼實現
配置如下:
<!--資料來源物件-->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="com.mysql.jdbc.Driver"></property>
<property name="jdbcUrl" value="jdbc:mysql:///test"></property>
<property name="user" value="root"></property>
<property name="password" value="root"></property>
</bean>
<!--jdbc模板物件-->
<bean id="jdbcTemplate" class="org.springframwork.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource">
<bean>
測試程式碼
@Test
//測試Spring產生jdbcTemplate物件
public void test2() throws PropertyVetoExeception{
ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
JdbcTemplate jdbcTemplate = app.getBean(JdbcTemplate.class);
int row = jdbcTemplate.update("insert into account values(?,?)","lisi",5000);
System.out.println(row);
}
spring產生模板物件程式碼實現(抽取jdbc.properties)
將資料庫的連線資訊抽取到外部配置檔案中,和spring的配置檔案分離開,有利於後期維護
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/test
jdbc.username=root
jdbc.password=root
配置檔案修改為:
<?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
">
<!--載入jdbc.properties-->
<context:property-placeholder location="classpath:jdbc.properties"/>
<!--資料來源物件-->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${jdbc.driver}"/>
<property name="jdbcUrl" value="${jdbc.url}"/>
<property name="user" 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>
常用操作-更新操作(應用)
package com.itheima.test;
import com.itheima.domain.Account;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
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.xml")
public class JdbcTemplateCRUDTest {
@Autowired
private JdbcTemplate jdbcTemplate;
//修改更新
@Test
public void testUpdate(){
jdbcTemplate.update("update account set money=? where name=?",10000,"tom");
}
//刪除
@Test
public void testDelete(){
jdbcTemplate.update("delete from account where name=?","tom");
}
}
知識要點(理解,記憶)
- 匯入spring-jdbc和spring-tx座標
- 建立資料庫表和實體
- 建立jdbcTemplate物件
JdbcTemplate jdbcTemplate = new JdbcTemplate();
jdbcTemplate.setDataSource(dataSource);
- 執行資料庫操作
更新操作:
jdbcTemplate.update (sql,params)
查詢操作:
jdbcTemplate.query (sql,Mapper,params)
jdbcTemplate.queryForObject(sql,Mapper,params)
宣告式事務控制
程式設計式事務控制相關物件
PlatformTransactionManager
PlatformTransactionManager介面是spring的事物管理器, 它裡面提供了我們常用的操作事務的方法.
方法 | 說明 |
---|---|
TransactionStatus getTransaction( TransactionDefination defination) | 獲取事務的狀態資訊 |
void commit (TransactionStatus status) | 提交事務 |
void rollback(TransactionStatus status) | 回滾事務 |
注意:
PlaformTransactionManager是介面型別, 不同的Dao層技術則有不同的實現類. 例如:Dao層技術是jdbc或mybatis時:
org.springframework.jdbc.datasource.DataSourceTransactionManager
Dao層技術是hibernate時:
org.springframework.orm.hibernate5.HibernateTransactionManager
TransactionDefinition
TransactionDefinition是事務的定義資訊物件,裡面有如下方法:
方法 | 說明 |
---|---|
int getIsolationLevel() | 獲得事務的隔離級別 |
int getPropogationBehavior() | 獲得事務的傳播行為 |
int getTimeout() | 獲得超時時間 |
boolean isReadOnly() | 是否只讀 |
1. 事務隔離級別
設定隔離級別, 可以解決事務併發產生的問題, 如髒讀\不可重複讀和虛讀.
- ISOLATION_DEFAULT
- ISOLATION_READ_UNCOMMTTED
- ISOLATION_READ_COMMTTED
- ISOLATION_REPEATABLE_READ
- ISOLATION_SERIALIZABLE
2. 事務傳播行為
- REQUIRED: 如果當前沒有事務, 就新建一個事務,如果已經存在一個事務中,加入到這個事務中, 一般的選擇(預設值)
- SUPPORTS:支援當前事務, 如果當前沒有事務, 就以非事務方式執行(沒有事務)
- MANDATORY: 使用當前的事物, 如果當前沒有事務,就丟擲異常.
- REQUERS_NEW: 新建事務, 如果當前在事務中,把當前事務掛起.
- NOT_SUPPORTED: 以非事務方式執行操作, 如果當前存在事務, 就把當前事務掛起
- NEVER: 以非事務方式執行, 如果當前存在事務,丟擲異常
- NESTED: 如果當前存在事務, 則在巢狀事務內執行, 如果當前沒有事務,則執行REQUIRED類似操作
- 超時時間: 預設值是-1, 沒有超時限制. 如果有,以秒為單位進行設定.
- 是否只讀: 建議查詢時設定為只讀
3. TransactionStatus
TransactionStatus介面提供的是事務具體的執行狀態,方法介紹如下
方法 | 說明 |
---|---|
boolean hashSavepoint() | 是否儲存回滾點 |
boolean isCOmpleted() | 事務是否完成 |
boolean isNewTransaction() | 是否是新事務 |
boolean isRollbackOnly() | 事務是否回滾 |
4. 知識要點
程式設計式事務控制三大物件
- PlatformTransactionManager
- TransactionDefinition
- TransactionStatus
2. 基於XML的宣告式事務控制
什麼是宣告式事務控制
spring的宣告式事務顧名思義就是採用宣告的方式來處理事務. 這裡所說的宣告,就是指在配置檔案中宣告,用在Spring 配置檔案中宣告式的處理事務來代替程式碼式的處理事務.
宣告式事務處理的作用
- 事務管理不侵入開發的元件. 具體來說, 業務邏輯物件就不會意識到正在事務管理之中, 事實上也應該如此因為事務管理是屬於系統層面的服務, 而不是業務邏輯的一部分, 如果想要改變事務管理策劃的話,也就需要在定義檔案中重新配置即可
- 在不需要事務管理的時候, 只要在設定檔案上修改一下, 即可移去事務管理服務, 無需改變程式碼重新編譯, 這樣維護起來及其方便.
注意: Spring 宣告式事務控制底層就是AOP.
宣告式事務控制的實現
宣告式事務控制明確事項:
- 誰是切點?
- 誰是通知
- 配置切面
- 引入tx名稱空間
<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/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
- 配置事務增強
<!--平臺事務管理器-->
<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="*"/>
</tx:attributes>
</tx:advice>
- 配置事務AOP織入
<!--事務的aop增強-->
<aop:config>
<aop:pointcut id="myPointcut" expression="execution(* com.itheima.service.impl.*.*(..))"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="myPointcut"></aop:advisor>
</aop:config>
- 測試事務控制轉賬業務程式碼
@Override
public void transfer(String outMan, String inMan, double money) {
accountDao.out(outMan,money);
int i = 1/0;
accountDao.in(inMan,money);
}
切點方法的事務引數的配置
<!--事務增強配置-->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="*"/>
</tx:atttributes>
</tx:advice>
其中,tx:method代表切點方法的事務引數的配置,例如:
<tx:method name="transfer" isolation="REPEATABLE_READ" propagation="REQUIRED" timeout="-1" read-only="false"/>
- name : 切點方法名稱
- isolation: 事務的隔離級別
- propogation: 事務的傳播行為
- timeout:超時時間
- read-only: 是否只讀
知識要點
宣告式事務控制的配置要點
- 平臺事務管理器配置
- 事務通知的配置
- 事務aop織入的配置
基於註解的宣告式事務控制
使用註解配置宣告式事務控制
- 編寫AccoutDao
@Repository("accountDao")
public class AccountDaoImpl implements AccountDao{
@Autowired
private JdbcTemplate jdbcTemplate;
public void out(String outMan , double money){
jdbcTemplate.update("update account set money = money-? where name=? ",money,outMan);
}
public void in(String inMan,double money){
jdbcTemplate.update("update account set money=money+? where name =?" ,money,inMan);
}
}
- 編寫AccountService
@Service("accountService")
@Transactional
public class AccountServiceImpl implements AccountService{
@Autowired
private AccountDao accountDao;
@Transactional(isolation = Isolation.READ_COMMITTED,propagation = Propagation.REQUIRED)
public void transfer(String outMan, String inMan, double money) {
accountDao.out(outMan,money);
int i = 1/0;
accountDao.in(inMan,money);
}
}
- 編寫 applicationContext.xml 配置檔案
<!—之前省略datsSource、jdbcTemplate、平臺事務管理器的配置-->
<!--元件掃描-->
<context:component-scan base-package="com.itheima"/>
<!--事務的註解驅動-->
<tx:annotation-driven/>
註解配置宣告式事務控制解析
①使用 @Transactional 在需要進行事務控制的類或是方法上修飾,註解可用的屬性同 xml 配置方式,例如隔離級別、傳播行為等。
②註解使用在類上,那麼該類下的所有方法都使用同一套註解引數配置。
③使用在方法上,不同的方法可以採用不同的事務引數配置。
④Xml配置檔案中要開啟事務的註解驅動<tx:annotation-driven />
知識要點
註解宣告式事務控制的配置要點
-
平臺事務管理器配置(xml方式)
-
事務通知的配置(@Transactional註解配置)
-
事務註解驅動的配置 tx:annotation-driven/
相關文章
- Spring筆記(4) - Spring的程式設計式事務和宣告式事務詳解Spring筆記程式設計
- 三 Spring 宣告式事務Spring
- Spring宣告式事務控制Spring
- Spring-宣告式事務Spring
- spring宣告式事務管理配置Spring
- Spring宣告式事務@Transactional使用Spring
- day15-宣告式事務
- Spring的事務管理(二)宣告式事務管理Spring
- Spring @Transactional 宣告式事務揭祕Spring
- 深刻理解Spring宣告式事務Spring
- day16-宣告式事務-02
- springboot專案-宣告式事務失效Spring Boot
- Spring宣告式事務控制原理之宣告式事務的重要元件在AOP中的應用Spring元件
- Springboot資料庫事務處理——Spring宣告式事務Spring Boot資料庫
- 五(二)、spring 宣告式事務xml配置SpringXML
- JavaEE(12)Spring整合Mybaits、宣告式事務JavaSpringAI
- Spring宣告式事務純xml模式回顧SpringXML模式
- Spring事務筆記Spring筆記
- Spring宣告式事務的兩種實現方式Spring
- mysql隱式提交事務transaction一點筆記MySql筆記
- Spring事務的介紹,以及基於註解@Transactional的宣告式事務Spring
- Spring程式設計式和宣告式事務例項講解Spring程式設計
- SpringCloud學習筆記:宣告式呼叫Feign(4)SpringGCCloud筆記
- MySQL 筆記 - 事務&鎖MySql筆記
- SQL筆記(14)——事務SQL筆記
- 保護億萬資料安全,Spring有“宣告式事務”絕招Spring
- 實現宣告式鎖,支援分散式鎖自定義鎖、SpEL和結合事務分散式
- 筆記:DB常用sql列印+事務使用筆記SQL
- spring事物配置,宣告式事務管理和基於@Transactional註解的使用Spring
- 【C++進階筆記】(1)函式模板的宣告及使用C++筆記函式
- Spring/SpringBoot中的宣告式事務和程式設計式事務原始碼、區別、優缺點、適用場景、實戰Spring Boot程式設計原始碼
- [高效能MYSQL學習筆記]事務MySql筆記
- 分散式事務(一)—分散式事務的概念分散式
- Kubernetes學習筆記(八):Deployment--宣告式的升級應用筆記
- Spring Cloud Feign 宣告式服務呼叫SpringCloud
- 宣告式服務呼叫 Spring Cloud FeignSpringCloud
- 分散式事務之Spring事務與JMS事務(二)分散式Spring
- Spring學習筆記3(JDBC模板&事務管理)Spring筆記JDBC