##從JDBC到Mybatis ###JDBC操做數據庫過程java
加載JDBC驅動程序員
創建並獲取數據庫鏈接數據庫
建立JDBC Statements對象緩存
設置SQL語句的傳入參數session
執行SQL語句並獲取查詢結果數據結構
對查詢結果進行轉換處理並將處理結果返回app
釋放相關資源(關閉Connection,關閉Statement,關閉ResultSet)模塊化
###Mybatis操做數據庫過程性能
從配置文件(一般是XML配置文件中)獲得 sessionfactory優化
由sessionfactory產生session
在session中完成對數據的增刪改查和事務提交等
用完以後關閉session
備註:在java對象和數據庫之間有作mapping的配置文件,也一般是xml文件。
##Mybatis對於JDBC的優化
問題描述:
數據庫鏈接頻繁的開啓和關閉自己就形成了資源的浪費,影響系統的性能。
解決問題:
數據庫鏈接的獲取和關閉咱們可使用數據庫鏈接池來解決資源浪費的問題。經過鏈接池就能夠反覆利用已經創建的鏈接去訪問數據庫了。減小鏈接的開啓和關閉的時間。
問題描述:
當鏈接池多種多樣,可能存在變化,有可能採用DBCP的鏈接池,也有可能採用容器自己的JNDI數據庫鏈接池。
解決問題:
們能夠經過DataSource進行隔離解耦,咱們統一從DataSource裏面獲取數據庫鏈接,DataSource具體由DBCP實現仍是由容器的JNDI實現均可以,因此咱們將DataSource的具體實現經過讓用戶配置來應對變化。
問題描述:
咱們使用JDBC進行操做數據庫時,SQL語句基本都散落在各個JAVA類中,這樣有三個不足之處: 第一,可讀性不好,不利於維護以及作性能調優。 第二,改動Java代碼須要從新編譯、打包部署。 第三,不利於取出SQL在數據庫客戶端執行(取出後還得刪掉中間的Java代碼,編寫好的SQL語句寫好後還得經過+號在Java進行拼湊)。
解決問題:
咱們能夠考慮不把SQL語句寫到Java代碼中,那麼把SQL語句放到哪裏呢? (1)首先須要有一個統一存放的地方,咱們能夠將這些SQL語句統一集中放到配置文件或者數據庫裏面(以key-value的格式存放)。 (2)而後經過SQL語句的key值去獲取對應的SQL語句。既然咱們將SQL語句都統一放在配置文件或者數據庫中,那麼這裏就涉及一個SQL語句的加載問題。
問題描述:
不少狀況下,咱們均可以經過在SQL語句中設置佔位符來達到使用傳入參數的目的,這種方式自己就有必定侷限性,它是按照必定順序傳入參數的,要與佔位符一一匹配。可是,若是咱們傳入的參數是不肯定的(好比列表查詢,根據用戶填寫的查詢條件不一樣,傳入查詢的參數也是不一樣的,有時是一個參數、有時多是三個參數),那麼咱們就得在後臺代碼中本身根據請求的傳入參數去拼湊相應的SQL語句,這樣的話仍是避免不了在Java代碼裏面寫SQL語句的命運。既然咱們已經把SQL語句統一存放在配置文件或者數據庫中了,怎麼作到可以根據前臺傳入參數不一樣,動態生成對應的SQL語句呢?
解決問題:
咱們先解決這個動態問題,按照咱們正常的程序員思惟是,經過if和else這類的判斷來進行是最直觀的,這個時候咱們想到了JSTL中的<if test=」」></if>這樣的標籤,那麼,能不能將這類的標籤引入到SQL語句中呢?假設能夠,那麼咱們這裏就須要一個專門的SQL解析器來解析這樣的SQL語句,可是,if判斷的變量來自於哪裏呢?傳入的值自己是可變的,那麼咱們得爲這個值定義一個不變的變量名稱,並且這個變量名稱必須和對應的值要有對應關係,能夠經過這個變量名稱找到對應的值,這個時候咱們想到了key-value的Map。解析的時候根據變量名的具體值來判斷。假如前面能夠判斷沒有問題,那麼假如判斷的結果是true,那麼就須要輸出的標籤裏面的SQL片斷,可是怎麼解決在標籤裏面使用變量名稱的問題呢?這裏咱們須要使用一種有別於SQL的語法來嵌入變量(好比使用#{變量名})。這樣,SQL語句通過解析後就能夠動態的生成符合上下文的SQL語句。
問題描述:
執行SQL語句、獲取執行結果、對執行結果進行轉換處理、釋放相關資源是一整套下來的。假如是執行查詢語句,那麼執行SQL語句後,返回的是一個ResultSet結果集,這個時候咱們就須要將ResultSet對象的數據取出來,否則等到釋放資源時就取不到這些結果信息了。咱們從前面的優化來看,以及將獲取鏈接、設置傳入參數、執行SQL語句、釋放資源這些都封裝起來了,只剩下結果處理這塊尚未進行封裝,若是能封裝起來,每一個數據庫操做都不用本身寫那麼一大堆Java代碼,直接調用一個封裝的方法就能夠搞定了。
解決問題:
們分析一下,通常對執行結果的有哪些處理,有可能將結果不作任何處理就直接返回,也有可能將結果轉換成一個JavaBean對象返回、一個Map返回、一個List返回等等,結果處理多是多種多樣的。從這裏看,咱們必須告訴SQL處理器兩點:第一,須要返回什麼類型的對象;第二,須要返回的對象的數據結構怎麼跟執行的結果映射,這樣才能將具體的值copy到對應的數據結構上。接下來,咱們能夠進而考慮對SQL執行結果的緩存來提高性能。緩存數據都是key-value的格式,那麼這個key怎麼來呢?怎麼保證惟一呢?即便同一條SQL語句幾回訪問的過程當中因爲傳入參數的不一樣,獲得的執行SQL語句也是不一樣的。那麼緩存起來的時候是多對。能夠將SQL語句和傳入參數兩部分合起來能夠做爲數據緩存的key值。
問題描述:
因爲咱們將全部SQL語句都放到配置文件中,這個時候會遇到一個SQL重複的問題,幾個功能的SQL語句其實都差很少,有些多是SELECT後面那段不一樣、有些多是WHERE語句不一樣。有時候表結構改了,那麼咱們就須要改多個地方,不利於維護。
解決問題:
當咱們的代碼程序出現重複代碼時怎麼辦?將重複的代碼抽離出來成爲獨立的一個類,而後在各個須要使用的地方進行引用。對於SQL重複的問題,咱們也能夠採用這種方式,經過將SQL片斷模塊化,將重複的SQL片斷獨立成一個SQL塊,而後在各個SQL語句引用重複的SQL塊,這樣須要修改時只須要修改一處便可。
###優化總結
使用數據庫鏈接池對鏈接進行管理
SQL語句統一存放到配置文件
SQL語句變量和傳入參數的映射以及動態SQL
動態SQL語句的處理
對數據庫操做結果的映射和結果緩存
SQL語句的重複