(三)Spring的數(shù)據(jù)庫開發(fā)

??DAO(Data Access Object)是用于訪問數(shù)據(jù)的對象,雖然在大多數(shù)情況下將數(shù)據(jù)保存在數(shù)據(jù)庫中,但這并不是唯一的選擇,也可以將數(shù)據(jù)存儲到文件中或LDAP中。DAO不但屏蔽了數(shù)據(jù)的最終介質(zhì)的不同,也屏蔽了具體的實現(xiàn)技術(shù)的不同。
??早期,JDBC是訪問數(shù)據(jù)庫的主流選擇。近幾年,隨這個數(shù)據(jù)持久化技術(shù)獲得了長足的發(fā)展,Hibernate、Mybatis等技術(shù)成為持久層框架的更好選擇。

Spring統(tǒng)一數(shù)據(jù)訪問模板

??到一個餐館用餐,大抵會經(jīng)歷這樣一個流程:進入餐館→服務人員問候并領(lǐng)到合適位置→拿起菜單點菜→用餐→買單→離開餐館。之所以我們喜歡時不時到餐館用餐,就是因為我們只要點菜→用餐→買單就可以了,其他工作我們不關(guān)心,餐館完成即可。
??在直接使用具體的持久化技術(shù)時,大多需要處理整個流程,程序員并沒有享受到“餐館用餐”般的好體驗。Spring為支持持久化技術(shù)分別提供了模板訪問的方式,降低了使用各種持久化技術(shù)的難度,因此可大幅度地提高開發(fā)效率。

使用模板和回調(diào)機制

??我們來看一下傳統(tǒng)的JDBC連接方式:

    Class.forName("JDBC驅(qū)動類的名稱");
    Connection con = null;
    PreparedStatement stmt = null;
try{
    //1.獲取資源
    con= DriverManager.getConnection(數(shù)據(jù)庫連接字符串,數(shù)據(jù)庫用戶名,密碼);
    //2.啟動事務
    con.setAutoCommit(false);
    //3.具體業(yè)務邏輯
    stmt=con.prepareStatement("插入數(shù)據(jù)");

    //4.提交事務
   con.commit();
}  catch(Exception e){
try{
    //5.回滾事務
    con.rollback();
}  catch...
    ...
    //6.關(guān)閉資源
    stmt.close();
    con.close();

??如上述代碼所示,JDBC數(shù)據(jù)訪問數(shù)據(jù)操作按一下流程進行:(1)準備資源(2)啟動事務(3)在事務中執(zhí)行具體的數(shù)據(jù)訪問操作(4)提交/回滾事務(5)關(guān)閉資源,處理異常。
??按照傳統(tǒng)的方式,在編寫任何帶事務的數(shù)據(jù)訪問程序時,都需要重復編寫上面的代碼,而其中只有具體業(yè)務邏輯和業(yè)務相關(guān),其他代碼都是重復的。
??Spring將這個相同的數(shù)據(jù)訪問流程固化到模板中,并將數(shù)據(jù)訪問中固定和變化的部分分開,同時保證模板類是線程安全的,以便多個數(shù)據(jù)訪問線程共享同一個模板實例。固定的部分在模板類中已經(jīng)準備好,而變化的部分通過回調(diào)接口開放處理,用于定義具體數(shù)據(jù)訪問和結(jié)果返回的操作,如下圖:

Spring Dao模板和回調(diào)

??這樣,只要編寫好回調(diào)接口,并調(diào)用模板類進行數(shù)據(jù)訪問,就能得到預期的結(jié)果:數(shù)據(jù)訪問成功執(zhí)行,前置和后置的樣板化工作也按順序正確執(zhí)行,在提高開發(fā)效率的同時也保證了資源使用的正確性,徹底消除了因忘記資源釋放而引起的資源泄露問題。

Spring為不同持久化技術(shù)提供模板

??Spring為各種支持的持久化技術(shù)都提供了建行操作的模板和回調(diào),在回調(diào)中編寫具體的數(shù)據(jù)操作邏輯,使用模板執(zhí)行數(shù)據(jù)操作,這是Spring中典型的數(shù)據(jù)操作模式。我們會介紹其中幾個。


數(shù)據(jù)源

??不管使用何種持久化技術(shù),都必須擁有數(shù)據(jù)連接。在Spring中,數(shù)據(jù)連接是通過數(shù)據(jù)源獲得的。在以往的應用中,數(shù)據(jù)源一般是由Web應用服務器提供的。在Spring中,不但可以通過JNDI獲取應用服務器的數(shù)據(jù)源,也可以直接在Spring容器中配置數(shù)據(jù)源,此外,還可以通過代碼的方式創(chuàng)建一個數(shù)據(jù)源。

配置一個數(shù)據(jù)源

??Spring在第三方依賴包中包含了兩個數(shù)據(jù)源的實現(xiàn)類包:DBCPC3P0。這個應該里都用過,我們可以在Spring文件中利用二者中的任何一個配置數(shù)據(jù)源。使用前請加入依賴包。

1.DBCP數(shù)據(jù)源
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    <bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close"
          p:driverClassName="com.mysql.jdbc.Driver"
          p:url="jdbc:mysql://localhost:3306/test"
          p:username="root"
          p:password="123456"
    />
</beans>
2.C3P0數(shù)據(jù)源
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close"
          p:driverClass="com.mysql.jdbc.Driver"
          p:jdbcUrl="jdbc:mysql://localhost:3306/test"
          p:user="root"
          p:password="123456"
/>

??當然,它們的屬性不僅僅于此,還有什么最大連接數(shù),空閑時間之類等,此處不做介紹,具體環(huán)境具體應用。

3.JNDI數(shù)據(jù)源(了解)
4.Spring的數(shù)據(jù)源實現(xiàn)類(了解)

使用屬性文件

??數(shù)據(jù)源的配置信息有可能經(jīng)常需要改動,同時可能被其他工程復用。此外,用戶名、密碼等信息比較敏感,可能需要加密措施。所以一般將數(shù)據(jù)源的配置信息獨立到一個屬性文件中,通過<context:property-placeholder>引入屬性文件,以${xxx}的方式引用屬性即可,代碼如下:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p"
       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">
    //引入WEB-INF目錄下的文件
    <context:property-placeholder location="WEB-INF/db.properties"/>
    <bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close"
          p:driverClassName="${jdbc.driverClass}"
          p:url="${jdbc.url}"
          p:username="${jdbc.username}"
          p:password="${jdbc.password}"
    />
</beans>

??在WEB-INF目錄下創(chuàng)建的db.properties文件:

jdbc.driverClass=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/test
jdbc.username=root
jdbc.password=123

??此處,屬性文件的內(nèi)容是以明文方式存放的,也可進行加密,此處不介紹。

Spring的JDBC訪問數(shù)據(jù)庫(了解即可)

??前面說過傳統(tǒng)的JDBC方式的缺點,Spring通過目標和回調(diào)機制大大降低了使用JDBC的復雜度,借由JdbcTemplate的幫助,僅需要編寫那些“必不可少”的代碼就可以進行數(shù)據(jù)庫操作,而將資源獲取、Statement創(chuàng)建、資源釋放及異常處理等繁雜且乏味的工作交給Spring JDBC。

什么是JdbcTemplate?

??JdbcTemplate類是Spring框架數(shù)據(jù)抽象層的基礎(chǔ),它是Spring JDBC的核心類,繼承結(jié)構(gòu)如下:


??從JdbcTemplate繼承關(guān)系圖可以看出,JdbcTemplate的直接父類是JdbcAccessor,該類為子類提供了一些訪問數(shù)據(jù)庫時的公用屬性。

  • DataSource:其主要功能是獲取數(shù)據(jù)庫的連接,還可以引入對數(shù)據(jù)庫連接的緩存池和分布式事務的支持,它可以作為訪問數(shù)據(jù)庫資源的標準接口。
  • SQLExceptionTranslator:該接口負責對SQLException進行轉(zhuǎn)譯工作。通過必要的設(shè)置獲取SQLExceptionTranslator的方法,可以使JdbcTemplate在需要處理SQLException時,委托給SQLExceptionTranslator的實現(xiàn)類來完成相關(guān)的轉(zhuǎn)譯工作。
    ??而JdbcOperations接口定義了在JdbcTemplate類中可以使用的操作集合,包括添加、修改、查詢和刪除等操作。

使用JdbcTemplate

??幾乎可以使用JdbcTemplate完成任何數(shù)據(jù)訪問操作,并充分享受它帶來的簡潔。它的使用方式有兩種:
1.代碼方式實現(xiàn)(了解即可)

//創(chuàng)建數(shù)據(jù)源并設(shè)置相關(guān)信息
DriverManagerDataSource ds = new DriverManagerDataSource();
ds.setDriverClassName("");
ds.setUrl("");
ds.setUsername("");
ds.setPassword("");

JdbcTemplate jtp = new JdbcTemplate();
//設(shè)置數(shù)據(jù)源
jtp.setDataSource(ds);

String sql = "create table user(user_id int ,username varchar(50))";
jtp.insert(sql);

2.配置文件使用(常用)
??當然,我們一般都是在配置文件中配置,直接在DAO中注入即可:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p"
       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">
    <!--掃描相應包注冊以注解方式聲明的Bean-->
    <context:component-scan base-package="cn"/>

    <!--1.定義數(shù)據(jù)源-->
    <context:property-placeholder location="WEB-INF/db.properties"/>
    <bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close"
          p:driverClassName="${jdbc.driverClass}"
          p:url="${jdbc.url}"
          p:username="${jdbc.username}"
          p:password="${jdbc.password}"
    />
    <!--2.聲明JdbcTemplate,并引用相應數(shù)據(jù)源-->
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"
          p:dataSource-ref="dataSource"/>
</beans>

然后在DAO中注入即可:

@Repository
public class UserDao{
        private JdbcTemplate jdbcTemplate;

        @Autowired
        public void setJdbcTemplate(JdbcTemplate jdbcTemplate){
        this.jdbcTemplate = jdbcTemplate;
        }

        public void saveUser(){
        String sql ="sql語句";
        jdbcTemplate.execute(sql);
        }
}

jdbcTemplate的數(shù)據(jù)庫操作方法

??數(shù)據(jù)庫的增、刪、查、改存儲過程調(diào)用是最常見的數(shù)據(jù)庫操作,jdbcTemplate提供了眾多方法完成這些數(shù)據(jù)操作。

  • execute:用于執(zhí)行sql語句。
  • update::用于執(zhí)行插入、更新和刪除操作。
  • query:用于執(zhí)行數(shù)據(jù)查詢操作。
    ??不詳細介紹了,因為我們一般都用Mybatis框架來代替Spring自帶的JDBC。

參考資料

《精通Spring 4.x 企業(yè)應用開發(fā)》

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關(guān)閱讀更多精彩內(nèi)容

  • 原文鏈接:https://docs.spring.io/spring-boot/docs/1.4.x/refere...
    pseudo_niaonao閱讀 4,893評論 0 9
  • 一年又一年,字節(jié)跳動 Lark(飛書) 研發(fā)團隊又雙叒叕開始招新生啦!【內(nèi)推碼】:GTPUVBA【內(nèi)推鏈接】:ht...
    盧卡斯嗶嗶嗶閱讀 20,135評論 0 4
  • 這篇文章是基于我開發(fā)讀寫分離中間件和數(shù)據(jù)庫智能運維平臺時的經(jīng)驗總結(jié)而成。網(wǎng)上對數(shù)據(jù)庫連接系統(tǒng)分析的文章非常少,甚至...
    彥幀閱讀 5,197評論 0 4
  • 柴靜頂著炎炎烈日走街串戶,她買了整整兩大筐土雞蛋!那付從未擔過擔子的肩頭,被那根柳木扁擔壓得又紅又腫,額角的汗水,...
    半盞流年02閱讀 250評論 0 1
  • 人物:唐僧、孫悟空、八戒、多個蜘蛛精。我們女生少,要反串。氣球填胸。 旁白:在有山有水風景秀麗的蘇州東山太湖邊上,...
    根蓮說閱讀 429評論 0 0

友情鏈接更多精彩內(nèi)容