SpringJDBC
- JDBC模板技術概述
- JDBC的模板類的使用
- Spring框架的事務管理
- 配置文件方式
- 半注解的方式
- 純注解的方式
JDBC模板技術概述
什么是 JDBC 模板技術?
JDBC 模板技術是 Spring 框架為簡化持久層(數據庫操作)編程而提供的一種封裝機制,核心類為JdbcTemplate。它基于模板設計模式,將 JDBC 操作中重復、繁瑣的底層代碼進行封裝,讓開發者只需關注核心業務邏輯(如 SQL 語句編寫、結果集處理)。
模板(template)技術的設計思想:
Spring 框架中提供了一系列以XxxTemplate命名的模板類(如JdbcTemplate、HibernateTemplate、RedisTemplate等),其核心思想是:將固定流程的代碼封裝為模板,將可變的業務邏輯通過回調接口暴露給開發者。
對于 JDBC 操作而言,固定流程包括:獲取數據庫連接(Connection)、創建 SQL 執行對象(Statement/PreparedStatement)、執行 SQL 語句、處理異常(如SQLException)、釋放資源(關閉ResultSet、Statement、Connection)
JdbcTemplate將這些固定流程封裝,開發者只需提供 SQL 語句和結果處理邏輯即可。
JDBC的模板類的使用
創建 maven java 工程,引入坐標依賴
<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>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><dependency><groupId>aopalliance</groupId><artifactId>aopalliance</artifactId><version>1.0</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-aspects</artifactId><version>5.0.2.RELEASE</version></dependency><dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId><version>1.8.13</version></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.6</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></dependencies>
new 對象的方式
編寫測試代碼
import org.junit.Test;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DriverManagerDataSource;public class Demo {/*** 使用的是 Spring 框架內置的連接池* 使用 new 對象方式完成*/@Testpublic void run1(){// 創建連接池對象,Spring 框架內置了連接池對象DriverManagerDataSource dataSource = new DriverManagerDataSource();// 設置 4 個參數dataSource.setDriverClassName("com.mysql.jdbc.Driver");dataSource.setUrl("jdbc:mysql:///ssm");dataSource.setUsername("root");dataSource.setPassword("root");// 提供模板,創建對象JdbcTemplate template = new JdbcTemplate(dataSource);// 完成數據的增刪改查template.update("insert into account values (null,?,?)","熊大 ",1000);}
}
使用 Spring 框架管理模板類
applicationContext_jdbc.xml
<!--配置連接池--><bean id="dataSource"class="org.springframework.jdbc.datasource.DriverManagerDataSource"><property name="driverClassName" value="com.mysql.jdbc.Driver"/><property name="url" value="jdbc:mysql:///ssm" /><property name="username" value="root" /><property name="password" value="root" /></bean><!--配置 jdbc 模板--><bean id="jdbcTemplate"class="org.springframework.jdbc.core.JdbcTemplate"><property name="dataSource" ref="dataSource" /></bean>
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;@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(value = "classpath:applicationContext_jdbc.xml")
public class Demo1 {@Autowiredprivate JdbcTemplate jdbcTemplate;/*** 測試的方式* 使用開源連接池*/@Testpublic void run1(){jdbcTemplate.update("insert into account values (null,?,?)"," 小麗",500);}
}
Spring 框架管理開源的連接池
配置開源的連接池,使用 Druid 開源的連接池,引入坐標依賴
<dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.1.10</version></dependency>
將數據庫連接的信息配置到屬性文件中
配置數據庫訪問相關的組件
<!--加載屬性文件--><bean id="placeholderConfigurer"class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"><!-- 指定屬性文件路徑:classpath表示從類路徑下查找 --><property name="location" value="classpath:jdbc.properties" /></bean><!--加載屬性文件第二種寫法:使用提供標簽的方式--><!--<context:property-placeholderlocation="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><!--配置 jdbc 模板--><bean id="jdbcTemplate"class="org.springframework.jdbc.core.JdbcTemplate"><property name="dataSource" ref="dataSource" /></bean>
- 加載外部屬性文件(數據庫配置信息)
<bean id="placeholderConfigurer">
定義了PropertyPlaceholderConfigurer組件,作用是加載類路徑(classpath)下的jdbc.properties屬性文件,通過這種方式,數據庫連接信息可以寫在外部的jdbc.properties文件中,而非硬編碼在 XML 里,便于后期修改和維護。<context:property-placeholder>
是另一種更簡潔的加載屬性文件的方式,功能完全一致。 - 配置數據庫連接池(Druid)
<bean id="dataSource">
定義了阿里巴巴的DruidDataSource(德魯伊連接池),其中的driverClassName、url、username、password屬性值使用${key}
格式的占位符,這些占位符會被前面加載的jdbc.properties文件中對應的鍵值對替換,通過配置連接池,應用可以高效地管理數據庫連接,避免頻繁創建 / 關閉連接的性能損耗。 - 配置 Spring JDBC 模板
<bean id="jdbcTemplate">
定義了 Spring 提供的JdbcTemplate組件,這是一個簡化 JDBC 操作的模板類,通過dataSource屬性引用了前面定義的dataSource(數據庫連接池),從而關聯到數據庫。
通過這段配置,Spring 容器會自動讀取外部 jdbc.properties 中的數據庫配置、初始化 Druid 連接池管理數據庫連接、初始化 JdbcTemplate 并關聯連接池。最終,應用可以直接從 Spring 容器中獲取 jdbcTemplate 對象,便捷地進行數據庫操作,同時數據庫配置可通過修改 jdbc.properties 靈活調整,無需改動 XML 配置。
增刪改查代碼編寫
import com.qcby.Model.Account;
import com.qcby.Model.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(value = "classpath:applicationContext_jdbc.xml")
public class Demo2 {@Autowiredprivate JdbcTemplate jdbcTemplate;/*** 測試的方式* 加載屬性文件的方式*/@Testpublic void run1(){jdbcTemplate.update("insert into account values (null,?,?)"," 熊四",800);}/*** 修改*/@Testpublic void run2(){jdbcTemplate.update("update account set name = ?,money = ? where id = ?","光頭強",100,7);}/*** 刪除*/@Testpublic void run3(){jdbcTemplate.update("delete from account where id = ?",7);}/*** 通過 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);}}
}
public class Account {private int id;private String name;private double money;public int getId() {return id;}public void setId(int 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 +'}';}
}
Account類是account數據庫表的映射實體類,屬性對應數據表中的字段,作為數據載體,封裝從數據庫查詢到的記錄,或封裝要插入或更新的數據。
import org.springframework.jdbc.core.RowMapper;import java.sql.ResultSet;
import java.sql.SQLException;/*** 實現類,用來進行數據封裝的*/
public class BeanMapper implements RowMapper<Account>{public Account mapRow(ResultSet resultSet, int i) throws SQLException {/*** 逐行進行數據封裝*/Account account = new Account();account.setId(resultSet.getInt("id"));account.setName(resultSet.getString("name"));account.setMoney(resultSet.getDouble("money"));return account;}
}
BeanMapper 類是結果集映射器的實現類,它實現了Spring JDBC的 RowMapper 函數式接口并指定泛型為 Account,核心職責是將數據庫查詢返回的 ResultSet 結果集逐行轉換為 Account 類型對象。
RowMapper 接口僅定義抽象方法 mapRow,BeanMapper 通過實現該方法定義具體行映射邏輯:當 JdbcTemplate 執行查詢并遍歷 ResultSet 時,每處理一行數據便調用 mapRow 方法,傳入當前行 ResultSet 實例及行索引;mapRow 從結果集中提取對應字段值,賦值給新創建的 Account 對象并返回。
此實現解決了數據庫結果集與Java對象的映射問題,使 JdbcTemplate 查詢可直接返回 Account 對象或其集合,便于以面向對象方式處理查詢結果。
實現效果:
使用JDBC模板操作數據庫實現模擬轉賬開發
Service 層代碼的編寫
public interface AccountService {/*** 轉賬的方法* @param out 付款人* @param in 收款人* @param money 金額*/public void pay(String out,String in,double money);
}
import com.qcby.dao.AccountDao;
import com.qcby.service.AccountService;public class AccountServiceImpl implements AccountService {private AccountDao accountDao;public void setAccountDao(AccountDao accountDao) {this.accountDao = accountDao;}public void pay(String out, String in, double money) {// 調用 dao 方法accountDao.outMoney(out,money);accountDao.inMoney(in,money);}
}
Dao 層代碼的編寫
public interface AccountDao {/*** 付款* @param out* @param money*/public void outMoney(String out,double money);/*** 收款* @param in* @param money*/public void inMoney(String in,double money);
}
import com.qcby.dao.AccountDao;
import org.springframework.jdbc.core.JdbcTemplate;public class AccountDaoImpl implements AccountDao{// 依賴Spring的JdbcTemplate,通過JdbcTemplate執行具體的SQL語句,操作數據庫private JdbcTemplate jdbcTemplate;//提供setter方法,讓Spring注入JdbcTemplatepublic void setJdbcTemplate(JdbcTemplate jdbcTemplate) {this.jdbcTemplate = jdbcTemplate;}/*** 付款* @param out* @param money*/public void outMoney(String out, double money) {jdbcTemplate.update("update account set money = money - ? where name = ?",money,out);}/*** 收款* @param in* @param money*/public void inMoney(String in, double money) {jdbcTemplate.update("update account set money = money + ? where name = ?",money,in);}
}
配置文件代碼編寫
<!--加載jdbc.properties文件,使用提供標簽的方式--><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><!--配置Jdbc模板類,創建JdbcTemplate對象,并注入dataSource--><bean id="jdbcTemplate"class="org.springframework.jdbc.core.JdbcTemplate"><property name="dataSource" ref="dataSource" /></bean><!--配置Service對象,注入Dao--><bean id="accountDao" class="com.qcby.dao.impl.AccountDaoImpl"><property name="jdbcTemplate" ref="jdbcTemplate" /></bean><!--配置Dao對象,注入JdbcTemplate--><bean id="accountService" class="com.qcby.service.impl.AccountServiceImpl"><property name="accountDao" ref="accountDao"/></bean>
測試代碼編寫
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(value = "classpath:applicationContext_dao1.xml")
public class Demo3 {@Autowiredprivate AccountService accountService;/*** 測試轉賬的方法*/@Testpublic void testPay(){accountService.pay("熊大","熊二",100);}
}
Dao 層編寫的第二種方式
import com.qcby.dao.AccountDao;
import org.springframework.jdbc.core.support.JdbcDaoSupport;public class AccountDaoImpl1 extends JdbcDaoSupport implements AccountDao {/*** 付款* @param out* @param money*/public void outMoney(String out, double money) {this.getJdbcTemplate().update("update account set money = money - ? where name = ?",money,out);}/*** 收款* @param in* @param money*/public void inMoney(String in, double money) {this.getJdbcTemplate().update("update account set money = money + ? where name = ?",money,in);}
}
AccountDaoImpl1 繼承了 Spring 提供的 JdbcDaoSupport 類,該類是 Spring 為簡化 JDBC 操作提供的工具類,內部已封裝了 JdbcTemplate 對象,子類可直接通過 getJdbcTemplate() 方法獲取 JdbcTemplate,無需手動定義和注入,減少重復代碼。
配置文件編寫
<!--第二種寫法:使用提供標簽的方式--><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><!--配置 service--><bean id="accountServicePx"class="com.qcby.service.impl.AccountServiceImpl"><property name="accountDao" ref="accountDao"/></bean><bean id="accountDao" class="com.qcby.dao.impl.AccountDaoImpl1"><property name="dataSource" ref="dataSource" /></bean>
編寫測試類
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(value = "classpath:applicationContext_dao2.xml")
public class Demo4 {@Autowiredprivate AccountService accountService;/*** 測試轉賬的方法*/@Testpublic void testPay(){accountService.pay("熊大","熊二",100);}
}
Spring框架的事務管理
核心接口與實現類
平臺事務管理器:PlatformTransactionManager
PlatformTransactionManager 是 Spring 事務管理的核心接口,定義了事務操作的標準規范,是事務執行器的角色。它屏蔽了不同持久層框架的事務差異,開發者需根據實際使用的持久層技術選擇對應的實現類。Spring 為不同的持久層框架提供了對應的 PlatformTransactionManager 實現
如果使用的 Spring 的 JDBC 模板或者 MyBatis 框架,需要選擇 DataSourceTransactionManager 實現類
如果使用的是 Hibernate 的框架,需要選擇 HibernateTransactionManager 實現類
接口方法如下:
void commit(TransactionStatus status)
void rollback(TransactionStatus status)
事務規則定義:TransactionDefinition
TransactionDefinition 是事務規則描述的接口,定義了事務隔離級別、事務傳播行為,這些屬性決定了事務的運行規則。
配置文件方式
<?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-placeholderlocation="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><!--對 pay 進行增強,設置隔離級別,傳播行為,超時的時間--><tx:method name="pay" isolation="DEFAULT" propagation="REQUIRED" /><tx:method name="find*" read-only="true" /></tx:attributes></tx:advice><!--配置 AOP 的增強--><aop:config><!--Spring 框架提供系統通知,使用 advisor 標簽--><aop:advisor advice-ref="txAdvice" pointcut="execution(public* com.qcby.service.impl.AccountServiceImpl1.pay(..))" /></aop:config><!--配置 service--><bean id="accountServicePx"class="com.qcby.service.impl.AccountServiceImpl"><property name="accountDao" ref="accountDao"/></bean><!--配置 dao --><bean id="accountDao" class="com.qcby.dao.impl.AccountDaoImpl1"><property name="dataSource" ref="dataSource" /></bean>
</beans>
這段 XML 配置文件是Spring 框架基于 XML 實現聲明式事務管理的核心配置,同時整合了數據庫連接、數據訪問層、業務邏輯層的 Bean 定義,最終實現對AccountServiceImpl類中pay方法的事務增強。
tx:advice 是 Spring 提供的事務通知組件,無需手動編寫切面類和通知方法,是事務規則的載體,transaction-manager=“transactionManager” 關聯配置的事務管理器,通知需通過管理器執行事務操作,tx:attributes 定義哪些方法需要事務及事務的具體規則。
aop:advisor 是 Spring 的通知器,專門用于綁定事務通知(tx:advice)和切入點,區別于普通 AOP 的 aop:aspect,advisor 是 Spring 為事務等系統級通知提供的簡化標簽。advice-ref=“txAdvice” 關聯定義的事務通知,pointcut=“execution(…)” 定義切入點。
測試
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(value = "classpath:applicationContext_tx.xml")
public class Demo5 {@Autowiredprivate AccountService accountService;/*** 測試轉賬的方法*/@Testpublic void testPay(){accountService.pay("熊大","熊二",100);}
}
半注解的方式
<?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/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/txhttp://www.springframework.org/schema/tx/spring-tx.xsd"><!--開啟注解的掃描--><context:component-scan base-package="com.qcby" /><!--第二種寫法:使用提供標簽的方式--><context:property-placeholderlocation="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>
Dao 層代碼
@Repository("accountDao_1")
public class AccountDaoImpl_1 implements AccountDao {// 依賴Spring的JdbcTemplate,通過JdbcTemplate執行具體的SQL語句,操作數據庫private JdbcTemplate jdbcTemplate;//提供setter方法,讓Spring注入JdbcTemplate@Autowiredpublic void setJdbcTemplate(JdbcTemplate jdbcTemplate) {this.jdbcTemplate = jdbcTemplate;}/*** 付款* @param out* @param money*/public void outMoney(String out, double money) {jdbcTemplate.update("update account set money = money - ? where name = ?",money,out);}/*** 收款* @param in* @param money*/public void inMoney(String in, double money) {jdbcTemplate.update("update account set money = money + ? where name = ?",money,in);}
}
Service 層代碼
import com.qcby.dao.AccountDao;
import com.qcby.service.AccountService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
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_1 implements AccountService{@Autowired@Qualifier("accountDao_1")private AccountDao accountDao;/*** 轉賬方法* @param out 付款人* @param in 收款人* @param money 金額*/public void pay(String out, String in, double money) {// 調用 dao 方法accountDao.outMoney(out,money);// 模擬異常//int a = 1/0;accountDao.inMoney(in,money);}
}
測試
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(value = "classpath:applicationContext_tx1.xml")
public class Demo6 {@Autowiredprivate AccountService accountService;/*** 測試轉賬的方法*/@Testpublic void testPay(){accountService.pay("熊大","熊二",100);}
}
純注解的方式
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;import javax.annotation.Resource;
import javax.sql.DataSource;/*** 配置類* @author Administrator*/
@Configuration
@ComponentScan(basePackages="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:///ssm");dataSource.setUsername("root");dataSource.setPassword("root");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 PlatformTransactionManagercreateTransactionManager(DataSource dataSource) {DataSourceTransactionManager manager = new DataSourceTransactionManager(dataSource);return manager;}
}
@Configuration:標識當前類是一個 Spring 配置類,Spring 會掃描并解析其中的配置;
@ComponentScan(basePackages=“com.qcby”):開啟組件掃描,掃描指定包及其子包下的類,被@Component等注解標記的類會被自動注冊到 Spring 容器中;
@EnableTransactionManagement:半注解和純注解形式需要開啟 Spring 的注解式事務管理支持,與 XML 配置中的<tx:annotation-driven/>
作用相同;
創建并配置數據源DataSource,用于建立與數據庫的連接;創建JdbcTemplate實例,并注冊到 Spring 容器中,@Resource(name = “dataSource”) 用于指定注入名為 dataSource 的 Bean 到方法參數 dataSource 中,該注解不僅可以作用在屬性上,也可以以作用方法上;創建平臺事務管理器PlatformTransactionManager,是 Spring 事務管理的核心組件。使用DataSourceTransactionManager(基于數據源的事務管理器),同樣依賴dataSource,因為事務需要綁定數據庫連接。
測試
import com.qcby.config.SpringConfig;
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(classes = SpringConfig.class)
public class Demo7 {// 注入要測試的Service@Autowiredprivate AccountService accountService;@Testpublic void testNormalPay() {accountService.pay("熊大", "熊二", 100);System.out.println("正常轉賬測試完成");}
}