Spring框架學習第三天
Spring DAO
- DAO(Data Access Object)資料訪問物件
- Spring DAO為整合JDBC提供了封裝,簡化了DAO元件的編寫
- Spring DAO提供了AOP模式的事務處理
- Spring DAO提供了統一的異常處理層次,它包裝的異常型別
DataAccessException
繼承自RuntimeException
無須顯式的捕獲
Spring DAO所做的工作
- 對JDBC的操作進行封裝,簡化了JDBC的操作
- 對JDBC的事務進行了AOP模式的封裝,簡化了事物的管理和操作
- 對資料庫訪問中的異常,由原來的檢查異常,封裝成了繼承
RunTimeException
的非檢查異常DataAccessException
JDBCTemplate
這個類負責載入驅動、獲取連線、獲取執行環境和釋放資源 我們只需要關心sql的編寫和資料的處理
如何獲取JDBCTemplate
最直接的是繼承JDBCDAOSupport
這個類
如果不繼承JDBCDAOSupport
則需要自己注入模版
使用繼承的方式
- 準備一張表放入資料
- 寫一個產品的介面,介面中定義一個查詢產品資料的方法
- 先匯入
ioc
,aop
,dao
對應的jar包,寫一個介面的實現類繼承JDBCDAOSupport
並實現介面 - 使用模板和模板對應的方法完成資料量的查詢
- 測試dao實現類,看是否能獲取到對應的資料
以繼承JDBCDAOSupport的方式查詢資料
- 建立一張銀行賬戶表 並且建立對應的序列,最後使用序列作為主鍵值插入幾條資料
- 建立一個專案拷貝
ioc
,aop
,連線池
,資料庫驅動包
以及Spring容器對應的配置檔案
,開啟元件掃描和注入dataSource
- 寫一個介面定義一個查詢資料量的方法
- 寫一個介面的實現類,繼承
JDBCDAOSupport
,加標註@Repository
並且注入dataSource
,這個dataSource
要定義在xml中並且傳遞給父類 使用模板完成資料查詢 - 寫一個測試類測試功能
根據銀行卡號查詢一個銀行賬戶
- 建立表和序列以及插入資料
- 根據表設計實體類
- 在介面加一個根據卡號查詢賬戶的方法
- 在實現類中使用模板來完成功能(使用模板完成功能時,需要用到RowMapper的實現類)
- 測試
根據卡號和密碼查詢一個銀行賬戶
- 建立表和序列以及插入資料
- 根據表設計實體類
- 在介面加一個根據卡號和密碼查詢賬戶的方法
- 在實現類中使用模板來完成功能(使用模板完成功能時,需要用到RowMapper的實現類)
- 測試
查詢物件列表
給銀行賬戶表增加資料
- 介面中增加一個方法,傳入一個銀行賬戶物件進來,然後把這些資料傳入資料庫
- 實現類中實現這個方法
- 測試
Spring整合JDBC
JdbcTemplate提供了以下的主要方法
queryForInt()
queryForObject()
query()
update()
execute()
總結JDBCTemplate的方法
queryForInt
查詢資料的資料量
queryForObject
查詢資料的資料量,也可以查詢單個物件(使用到RowMapper)
query
查詢資料列表(也會用到RowMapper)
update
用來完成增刪改查
execute
一般用來執行DDL(建表、刪表、改表),用得比較少,但是有相關的業務還是得會!
不繼承JDBCDAOSupport的方式
就需要我們自己注入JDBCTemplate
使用模板和不使用模板的區別
-
繼承JDBCDAOSupport
與不繼承JDBCDAOSupport
-
注入的方式不同,例如:
使用模板
@Autowired public BankAccountDaoImp(DataSource dataSource) { super.setDataSource(dataSource); }
不使用模板
@Override public int getBankAccountCount() { String sql = "select count(*) from BANK_ACCOUNT_2018_11"; return jdbcTemplate.queryForObject(sql, Integer.class); }
Spring中的事務
把多個sql(dml,增刪改)操作看成一個邏輯整體,這些語句要求一起成功或者一起失敗
特性
- 原子性(事務中的語句是一個整體不可再分)
- 一致性(事務中的語句狀態要保持一致)
- 隔離性(隔離級別:髒讀、幻讀、不可重複讀)
詳細解釋隔離級別
髒讀:一個事務讀取到了另外一個事務沒有提交的資料 不可重複讀:一個事務在開始時讀取了一份資料,在事務的操作過程中,另外一個事務對你讀取的那份資料進行了修改(改動),並進行了提交,當第一個事務再次讀取資料時,發現數據發生了改變。 幻讀:一個事務在事務開始時對所有的資料進行了統計 在統計過程中資料發生了增加資料 再次統計所有資料時,資料改變了
為了解決三大讀問題,引入四個隔離級別 讀未提交 讀提交 可重複讀 序列化 1 2 3 4 永續性
Spring中事務的實現
- 程式設計式事務(使用大量Java程式碼完成事務)
- 宣告式事務(基於AOP程式設計)
Spring中宣告式事務的實現
Spring宣告式事務的優勢 通過Spring的配置,對事務管理而不是在原始碼進行直接編碼,解除了事務管理和程式碼的耦合,可以隨時從Spring容器中進行刪除
宣告式事務的實現步驟
- 開啟元件掃描和宣告式事務
<!--開啟元件掃描-->
<context:component-scan base-package="com.dao"/>
<!--開啟宣告式事務 transaction-manager就是事務管理器的意思,proxy-target-class如果是false代表jdk的代理機制(必須要求你的這個類實現介面),如果是true代表使用cglib的動態代理-->
<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/>
- 配置事務管理器和資料來源
<!--資料來源配置檔案-->
<util:properties id="db" location="classpath:db.properties"/>
<!--資料來源物件-->
<bean id="ds" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="#{db.driverClassName}"/>
<property name="url">
<value>#{db.url}</value>
</property>
<property name="username" value="#{db.username}"/>
<property name="password" value="#{db.password}"/>
</bean>
<!--建立事務管理器-->
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="ds"></property>
</bean>
- 在需要事務管理的方法或者類上加
@Transaction
標註
注意:實際上事務管理器可以不動任何原始碼!
@Transactional
註解標記有以下屬性,在使用時可以根據需要做特殊設定。
propagation:設定事務傳播
isolation:設定事務隔離級別
readOnly:設定為只讀,還是可讀寫
rollbackFor:設定遇到哪些異常必須回滾
noRollbackFor:設定遇到哪些異常不回滾