四、spring的JDBC模板和事務管理
阿新 • • 發佈:2019-01-14
Spring的JDBC模板
Spring是JavaEE開發的一站式框架,對各種持久化技術都提供了簡單的模板
ORM持久化技術 | 模板類 |
JDBC | org.springframework.jdbc.core.JdbcTemplate |
Hibernate5.0 | org.springframework.orm.hibernate5.HibernateTemplate |
IBatis(MyBatis) | org.springframework.orm.ibatis.SqlMapClientTemplate |
JPA | org.springfrmaework.orm.jpa.JpaTemplate |
JDBC模板的基本使用
- 引入jar
- Spring專案的6個基礎開發包
- 資料庫驅動包
- Spring的JDBC模板的jar包
- 測試
- 編寫測試類
public class TestDemo { @Test public void demo() { //建立連線池 DriverManagerDataSource dataSource = new DriverManagerDataSource(); dataSource.setDriverClassName("com.mysql.jdbc.Driver"); dataSource.setUrl("jdbc:mysql:///test"); dataSource.setUsername("root"); dataSource.setPassword("root"); //建立jdbc模板 JdbcTemplate template = new JdbcTemplate(dataSource); List<Map<String,Object>> list = template.queryForList("select * from user"); for (Map<String, Object> map : list) { Set<String> keySet = map.keySet(); Iterator<String> iterator = keySet.iterator(); while (iterator.hasNext()) { String key = iterator.next(); System.out.println(key+" : "+map.get(key)); } } } }
- 測試結果
id : 1 name : test password : 0 id : 2 name : wxf password : 1 id : 3 name : admin password : 123
- 編寫測試類
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: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"> <!-- 管理資料庫連線池 --> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="url" value="jdbc:mysql:///test"></property> <property name="driverClassName" value="com.mysql.jdbc.Driver"></property> <property name="username" value="root"></property> <property name="password" value="root"></property> </bean> <!-- 管理JDBC模板 --> <bean id="template" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource" ref="dataSource"/> </bean>
- 測試方法
@Test public void demo2() { ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); JdbcTemplate template = (JdbcTemplate) context.getBean("template"); List<Map<String,Object>> list = template.queryForList("select * from user"); for (Map<String, Object> map : list) { Set<String> keySet = map.keySet(); Iterator<String> iterator = keySet.iterator(); while (iterator.hasNext()) { String key = iterator.next(); System.out.println(key+" : "+map.get(key)); } } }
Spring中使用開源資料庫連線池
DBCP的使用
- 引入jar包
- com.springsource.org.apache.commons.pool-1.5.3.jar
- com.springsource.org.apache.commons.dbcp-1.2.2.osgi.jar
- Spring配置連線池
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"> <property name="url" value="jdbc:mysql:///test"></property> <property name="driverClassName" value="com.mysql.jdbc.Driver"></property> <property name="username" value="root"></property> <property name="password" value="root"></property> </bean>
C3P0的使用
- 引入jar包
- com.springsource.com.mchange.v2.c3p0-0.9.1.2.jar
- Spring配置連線池
<!-- 管理c3p0資料庫連線池 --> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <property name="jdbcUrl" value="jdbc:mysql:///test"></property> <property name="driverClass" value="com.mysql.jdbc.Driver"></property> <property name="user" value="root"></property> <property name="password" value="root"></property> </bean>
抽取連線池屬性配置值到Properties檔案
- 定義一個properties檔案:jdbc.properties
jdbc.url=jdbc:mysql:///test jdbc.driverClassName=com.mysql.jdbc.Driver jdbc.username=root jdbc.password=root
- Spring引入jdbc.properties檔案
- 第一種:使用<bean>標籤
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="location" value="classpath:jdbc.properties"/> </bean>
- 第二種:使用<context:property-placeholder>標籤
<context:property-placeholder location="classpath:jdbc.properties" />
- 第一種:使用<bean>標籤
- Spring配置檔案使用jdbc.properties的屬性值
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="url" value="${jdbc.url}"></property> <property name="driverClassName" value="${jdbc.driverClassName}"></property> <property name="username" value="${jdbc.username}"></property> <property name="password" value="${jdbc.password}"></property> </bean>
Spring的事務管理
常用API
PlatformTransactionManager
- Spring的事務基礎結構的中心介面,常用實現類
- DataSourceTransactionManager:使用JDBC管理事務
- HibernateTransactionManager:使用Hibernate管理事務
TransactionDefinition
- Spring的事務定義,用於定義事務相關的資訊。例如,隔離級別、傳播行為、是否只讀、超時資訊等
TransactionStatus
- 用於記錄事務管理的過程中,事務的狀態資訊
Spring進行事務管理時,PlatformTransactionManager根據TransactionDefinition進行事務的管理,這個過程中會產生各種狀態,將這些狀態記錄到TransactionStatus中
傳播行為
基本認識
事務傳播行為用來描述由某一個事務傳播行為修飾的方法被巢狀進另一個方法的時事務如何傳播
主要用來解決業務層方法(每個業務層方法有自己的事務)相互呼叫的問題
7種傳播行為
class TestServiceImpl01 { ... public void A() { testDao1.test1(); testDao2.test2(); } } class TestServiceImpl02 { ... public void B() { new TestServiceImpl01().A();//A操作 testDao3.test3();//B操作 testDao4.test4();//B操作 } }
分類 | 傳播行為型別 | 說明 |
多個操作在同一個事務中 (A、B操作在一個事務中) |
PROPAGATION_REQUIRED | 預設值,如果A中有事務,使用A中的事務;如果A中沒有事務,建立一個新的事務,將操作(A、B)包含進來 |
PROPAGATION_SUPPORTS | 如果A中有事務,使用A中的事務;如果A中沒有事務,就不使用事務 | |
PROPAGATION_MANDATORY | 如果A中有事務,使用A中的事務;如果A中沒有事務,就丟擲異常 | |
多個操作不在同一個事務中 (A、B操作不在一個事務中) |
PROPAGATION_REQUIRES_NEW | 如果A中有事務,將A的事務掛起,新建一個事務,只將自身操作(B)包含進來 |
PROPAGATION_NOT_SUPPORTED | 如果A中有事務,將A的事務掛起,不使用事務 | |
PROPAGATION_NEVER | 如果A中有事務,丟擲異常 | |
巢狀式事務 | PROPAGATION_NESTED | 如果A中有事務,執行A事務,執行完成後設定一個儲存點;再執行B中的操作,如果沒有異常,執行通過;如果有異常 可以回滾到最初始位置(A操作前),也可以回滾到A操作後設置的儲存點位置 |
基本使用
案例要求:
賬戶之間相互轉賬,一方轉出的同時另一方必須轉入才行
實現一:不使用事務
- 建立service層、dao層的介面和實現類
- dao層
- 介面
- 實現類
- service層
- 介面
- 實現類
- dao層
- Spring管理service和dao的實現類
- 測試
程式設計式、宣告式事務管理