本篇內(nèi)容主要講解“JDBC Template如何使用”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實(shí)用性強(qiáng)。下面就讓小編來帶大家學(xué)習(xí)“JDBC Template如何使用”吧!
創(chuàng)新互聯(lián)公司是一家做網(wǎng)站、成都網(wǎng)站設(shè)計(jì),提供網(wǎng)頁設(shè)計(jì),網(wǎng)站設(shè)計(jì),網(wǎng)站制作,建網(wǎng)站,按需策劃設(shè)計(jì),網(wǎng)站開發(fā)公司,從2013年開始是互聯(lián)行業(yè)建設(shè)者,服務(wù)者。以提升客戶品牌價值為核心業(yè)務(wù),全程參與項(xiàng)目的網(wǎng)站策劃設(shè)計(jì)制作,前端開發(fā),后臺程序制作以及后期項(xiàng)目運(yùn)營并提出專業(yè)建議和思路。
Spring
為開發(fā)者提供了JDBCTemplate
,可以簡化很多數(shù)據(jù)庫操作相關(guān)的代碼,本文主要介紹JDBCTemplate
的使用以及事務(wù)管理功能。
JDBC Template
配置的話主要配置以下幾項(xiàng):
數(shù)據(jù)源:org.springframework.jdbc.datasource.DriverManager.DataSource
數(shù)據(jù)庫驅(qū)動:com.cj.MySQL.jdbc.Driver
,這里采用的是MySQL 8
,注意MySQL 5.7
以下的驅(qū)動名字不同,另外若是其他數(shù)據(jù)庫請對應(yīng)修改
數(shù)據(jù)庫URL
:jdbc:mysql://localhost:3306/test
,MySQL
默認(rèn)的3306
端口,數(shù)據(jù)庫test
數(shù)據(jù)庫用戶名
數(shù)據(jù)庫密碼
JDBC
模板:org.springframework.jdbc.core.jdbcTemplate
參考配置如下:
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/test"/> <property name="username" value="test"/> <property name="password" value="test"/> </bean> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource" ref="dataSource"/> </bean> <context:component-scan base-package="pers.dao"/>
int update(String sql,Object args[])
:增/刪/改操作,使用args
設(shè)置其中的參數(shù),返回更新的行數(shù)
List<T> query(String sql,RowMapper<T> rowMapper,Object []args)
:查詢操作,rowMapper
將結(jié)果集映射到用戶自定義的類中
首先導(dǎo)入依賴:
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>5.2.9.RELEASE</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.21</version> </dependency>
MySQL
的版本請根據(jù)個人需要更改,或使用其他數(shù)據(jù)庫的驅(qū)動。
完整配置文件如下:
<?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 https://www.springframework.org/schema/context/spring-context.xsd"> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/test"/> <property name="username" value="test"/> <property name="password" value="test"/> </bean> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource" ref="dataSource"/> </bean> <context:component-scan base-package="pers.dao"/> </beans>
public class MyUser { private Integer id; private String uname; private String usex; }
添加@Repository
以及@RequiredArgsConstructor
:
@Repository @RequiredArgsConstructor(onConstructor = @__(@Autowired)) public class TestDao { private final JdbcTemplate template; public int update(String sql,Object[] args) { return template.update(sql,args); } public List<MyUser> query(String sql, Object[] args) { RowMapper<MyUser> mapper = new BeanPropertyRowMapper<>(MyUser.class); return template.query(sql,mapper,args); } }
因?yàn)橹苯邮褂?code>@Autowired的話會提示不推薦:
所以利用了Lombok
的注解@RequiredArgsConstructor
,效果相當(dāng)如下構(gòu)造方法,只不過是簡化了一點(diǎn):
@Autowired public TestDao(JdbcTemplate template) { this.template = template; }
測試之前先建表:
create table MyUser( id INT AUTO_INCREMENT PRIMARY KEY , uname varchar(20), usex varchar(20) )
測試類:
public class Main { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); TestDao dao = (TestDao)context.getBean("testDao"); String insertSql = "insert into MyUser(uname,usex) values(?,?)"; String[] param1 = {"chenhengfa1","男"}; String[] param2 = {"chenhengfa2","男"}; String[] param3 = {"chenhengfa3","男"}; String[] param4 = {"chenhengfa4","男"}; dao.update(insertSql,param1); dao.update(insertSql,param2); dao.update(insertSql,param3); dao.update(insertSql,param4); String selectSql = "select * from MyUser"; List<MyUser> list = dao.query(selectSql,null); for(MyUser mu:list) { System.out.println(mu); } } }
輸出:
如果出現(xiàn)異?;虿迦氩怀晒Φ绕渌闆r,請檢查SQL
語句是否編寫正確,包括表名以及字段名。
Spring
中的事務(wù)管理有兩種方法:
編程式事務(wù)管理:代碼中顯式調(diào)用beginTransaction
、commit
、rollback
等就是編程式事務(wù)管理
聲明式事務(wù)管理:通過AOP
實(shí)現(xiàn),不需要通過編程方式管理事務(wù),因此不需要再業(yè)務(wù)邏輯代碼中摻雜事務(wù)處理的代碼,開發(fā)更加簡單,便于后期維護(hù)
下面先來看一下編程式事務(wù)管理的實(shí)現(xiàn)。
編程式事務(wù)管理的配置又有兩種方法:
基于底層API
基于TransactionTemplate
需要的依賴如下:
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-tx</artifactId> <version>5.2.9.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-expression</artifactId> <version>5.2.9.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aop</artifactId> <version>5.2.9.RELEASE</version> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.9.6</version> <scope>runtime</scope> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aspects</artifactId> <version>5.2.9.RELEASE</version> </dependency>
API
實(shí)現(xiàn)根據(jù)PlatformTransactionManager
、TransactionDefinition
、TransactionStatus
幾個核心接口,通過編程方式進(jìn)行事務(wù)管理,首先配置事務(wù)管理器:
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"/> </bean>
接著修改數(shù)據(jù)庫訪問類:
@Repository @RequiredArgsConstructor(onConstructor = @__(@Autowired)) public class TestDao { private final JdbcTemplate template; private final DataSourceTransactionManager manager; public int update(String sql,Object[] args) { return template.update(sql,args); } public List<MyUser> query(String sql,Object[] args) { RowMapper<MyUser> mapper = new BeanPropertyRowMapper<>(MyUser.class); return template.query(sql,mapper,args); } public void testTransaction() { TransactionDefinition definition = new DefaultTransactionDefinition(); TransactionStatus status = manager.getTransaction(definition); String message = "執(zhí)行成功,沒有事務(wù)回滾"; try { String sql1 = "delete from MyUser"; String sql2 = "insert into MyUser(id,uname,usex) values(?,?,?)"; Object [] param2 = {1,"張三","男"}; template.update(sql1); template.update(sql2,param2); template.update(sql2,param2); manager.commit(status); } catch (Exception e) { e.printStackTrace(); manager.rollback(status); message = "主鍵重復(fù),事務(wù)回滾"; } System.out.println(message); } }
TransactionDefinition
是事務(wù)定義,是一個接口:
主要定義了:
事務(wù)隔離級別
事務(wù)傳播行為
事務(wù)超時時間
是否為只讀事務(wù)
而DefaultTransactionDefinition
就是上面屬性的一些默認(rèn)配置,比如:
也就是定義了:
傳播行為為0
:也就是常量PROPAGATION_REQUIREDE
,表示如果當(dāng)前存在一個事務(wù),則加入當(dāng)前事務(wù),如果不存在任何事務(wù),就創(chuàng)建一個新事務(wù)
隔離級別為-1
:這個也是TransactionDefinition
的默認(rèn)參數(shù),表示使用數(shù)據(jù)庫的默認(rèn)隔離級別,通常情況下為Read Committed
超時為-1
:默認(rèn)設(shè)置不超時,如需要設(shè)置超時請調(diào)用setTimeout
方法,比如如果設(shè)置為了60
,那么相當(dāng)于如果操作時間超過了60s
,而且后面還涉及到CRUD
操作,那么會拋出超時異常并回滾,如果超時操作的后面沒有涉及到CRUD
操作,那么不會回滾
只讀事務(wù)為false
:默認(rèn)為false
,但是該變量不是表明“不能”進(jìn)行修改等操作,而是一種暗示,如果不包含修改操作,那么JDBC
驅(qū)動和數(shù)據(jù)庫就有可能針對該事務(wù)進(jìn)行一些特定的優(yōu)化
具體執(zhí)行流程如下:
定義事務(wù):實(shí)例類為DefaultTransactionDefinition
開啟事務(wù):通過getTransaction(TransactionDefinition)
開啟
執(zhí)行業(yè)務(wù)方法
根據(jù)業(yè)務(wù)方法是否出現(xiàn)異常手動調(diào)用DataSourceTransaction
的commit(TransactionStatus)
進(jìn)行提交
出現(xiàn)異常調(diào)用rollback(TransactionStatus)
進(jìn)行回滾
測試如下:
TransactionTemplate
步驟:
通過調(diào)用TransactionTemplate
的execute
實(shí)現(xiàn)
execute
接受一個TransactionCallback
接口參數(shù)
TransactionCallback
定義了一個doInTransaction
方法
通常以匿名內(nèi)部類的方式實(shí)現(xiàn)TransactionCallback
接口,在其中的doInTransaction
編寫業(yè)務(wù)邏輯代碼
doInTransaction
有一個TransactionStatus
的參數(shù),可以調(diào)用setRollbackOnly
進(jìn)行回滾
默認(rèn)的回滾規(guī)則如下:
如果拋出未檢查異常或者手動調(diào)用setRollbackOnly
,則回滾
如果執(zhí)行完成或拋出檢查異常,則提交事務(wù)
示例如下,首先編寫配置文件對Bean
進(jìn)行注入:
<!--事務(wù)管理器--> <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"/> </bean> <!--事務(wù)模板--> <bean id="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate"> <property name="transactionManager" ref="txManager"/> </bean>
其次修改數(shù)據(jù)訪問類,添加一個測試方法:
public void testTransactionTemplate() { System.out.println(transactionTemplate.execute((TransactionCallback<Object>) transactionStatus -> { String deleteSql = "delete from MyUser"; String insertSql = "insert into MyUser(id,uname,usex) values(?,?,?)"; Object[] parm = {1, "張三", "男"}; try { template.update(deleteSql); template.update(insertSql, parm); template.update(insertSql, parm); } catch (Exception e) { message = "主鍵重復(fù),事務(wù)回滾"; e.printStackTrace(); } return message; })); }
大部分代碼與第一個例子類似就不解釋了,結(jié)果也是因?yàn)橹麈I重復(fù)出現(xiàn)異常,造成事務(wù)回滾:
Spring
聲明式事務(wù)管理通過AOP
實(shí)現(xiàn),本質(zhì)是在方法前后進(jìn)行攔截,在目標(biāo)方法開始之前創(chuàng)建或加入一個事務(wù),執(zhí)行目標(biāo)方法完成之后根據(jù)執(zhí)行情況提交或回滾事務(wù)。相比起編程式事務(wù)管理,聲明式最大的優(yōu)點(diǎn)就是不需要通過編程的方式管理事務(wù),業(yè)務(wù)邏輯代碼無需混雜事務(wù)代碼,但是唯一不足的地方就是最細(xì)粒度只能作用到方法上,而不能做到代碼塊級別。
實(shí)現(xiàn)方式有如下兩種:
基于XML
實(shí)現(xiàn)
基于@Transactional
實(shí)現(xiàn)
XML
Spring
提供了tx
命令空間來配置事務(wù):
<tx:advice>
:配置事務(wù)通知,一般需要指定id
以及transaction-manager
<tx:attributes>
:配置多個<tx:method>
指定執(zhí)行事務(wù)的細(xì)節(jié)
完整配置文件如下:
<?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:cache="http://www.springframework.org/schema/cache" 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 https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.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="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/test"/> <property name="username" value="test"/> <property name="password" value="test"/> </bean> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource" ref="dataSource"/> </bean> <context:component-scan base-package="pers.dao"/> <!--事務(wù)管理器--> <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"/> </bean> <bean id="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate"> <property name="transactionManager" ref="txManager"/> </bean> <!--聲明式事務(wù)--> <tx:advice id="myAdvice" transaction-manager="txManager"> <tx:attributes> <!--任意方法--> <tx:method name="*" /> </tx:attributes> </tx:advice> <!--aop配置,具體可以看筆者之前的文章--> <aop:config> <!--定義切點(diǎn),執(zhí)行testXMLTranscation()時進(jìn)行增強(qiáng)--> <aop:pointcut id="txPointCut" expression="execution(* pers.dao.TestDao.testXMLTransaction())"/> <!--切面--> <aop:advisor advice-ref="myAdvice" pointcut-ref="txPointCut"/> </aop:config> </beans>
測試方法如下:
public void testXMLTransaction() { String deleteSql = "delete from MyUser"; String saveSql = "insert into MyUser(id,uname,usex) values(?,?,?)"; Object [] parm = {1,"張三","男"}; template.update(deleteSql); template.update(saveSql,parm); template.update(saveSql,parm); }
運(yùn)行結(jié)果:
可以看到提示主鍵重復(fù)了。
@Transactional
@Transactional
一般作用于類上,使得該類所有public
方法都具有該類型的事務(wù)屬性。下面創(chuàng)建一個示例。
將上一個例子中的<aop:config>
以及<tx:advice>
注釋掉,同時添加:
<!--事務(wù)管理的注解驅(qū)動器--> <tx:annotation-driven transaction-manager="txManager"/>
測試方法與上一個例子一致,結(jié)果也是如此:
到此,相信大家對“JDBC Template如何使用”有了更深的了解,不妨來實(shí)際操作一番吧!這里是創(chuàng)新互聯(lián)網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!
新聞標(biāo)題:JDBCTemplate如何使用
文章URL:http://bm7419.com/article16/gejdgg.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供用戶體驗(yàn)、品牌網(wǎng)站設(shè)計(jì)、營銷型網(wǎng)站建設(shè)、網(wǎng)站維護(hù)、響應(yīng)式網(wǎng)站、電子商務(wù)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)