MyBatis框架總結

MyBatis

1.對原生態JDBC程序(單獨使用JDBC開發)的問題總結
2.MyBatis框架原理
3.MyBatis入門程序
        用戶的CRUD操作
4.MyBatis開發的兩種方法
        原始DAO開發方法(需要編程DAO接口和DAO實現類)(掌握)
        MyBatis的Mapper接口(相當於DAO接口)代理開發方法(掌握)
5.MyBatis配置文件SqlMapConfig.xml
6.MyBatis核心
        MyBatis輸入映射(掌握)
        MyBatis輸出映射(掌握)
7.MyBatis動態SQL(掌握)
8.MyBatis延遲加載
9.MyBatis查詢緩存(一級緩存,二級緩存)
10.MyBatis和Spring進行整合(掌握)
11.MyBatis逆向工程

框架架構圖


                                                                                 


parameterType
指定輸入參數的數據類型
此數據類型對應數據庫中表裏的字段的數據類型

resultType
指定輸出結果所映射的java對象類型

#{}和${}
#{}表示一個佔位符,#{}接收輸入參數,參數類型可以是簡單類型(int,String等基本數據類型),pojo,HashMap等
        如果接收簡單類型,#{}中可以寫成#{value}或者其他名稱
#{}接收pojo對象值,是通過OGNL()讀取對象中的屬性值,通過屬性.屬性.屬性的方式獲取對象屬性值

${}表示一個拼接符號,會引起SQL注入,所以不建議使用
${}接收輸入參數,參數類型可以是簡單類型(int,String等基本數據類型),pojo,HashMap等
        如果接收簡單類型,${}中只能寫成${value}
#{}接收pojo對象值,是通過OGNL()讀取對象中的屬性值,通過屬性.屬性.屬性的方式獲取對象屬性值

添加一條數據庫記錄返回自增主鍵值(MySQL)
將插入數據的主鍵返回到pojo對象中
【只適用於自增主鍵】
SELECT LAST_INSERT_ID():得到剛剛insert插入進數據庫的記錄的主鍵值
            
keyProperty:將查詢到的主鍵值設置到parameterType指定的對象的id屬性中
order:SELECT LAST_INSERT_ID()執行順序,相對於insert語句來說它的執行順序
resultType:指定SELECT LAST_INSERT_ID()的結果的數據類型

【注】:若是Oracle數據庫的話,把LAST_INSERT_ID()替換成Oracle中獲取序列的方法即可。


Hibernate和MyBatis本質的區別和應用場景
Hibernate:是一個標準的ORM(對象關係映射)框架,入門門檻比較高,不需要程序員寫SQL,其SQL語句是自動生成
難點:對SQL語句進行優化,修改比較困難。
應用場景:
        適用於需求變化不多的中小型的項目,比如:後臺管理系統,ERP,ORM,OA等等

MyBatis:專注SQL本身,需要程序員自己編寫SQL語句,SQL的修改和優化比較方便。
MyBatis是一個不完全的ORM框架,雖然程序員自己寫SQL,但是MyBatis也可以實現映射(輸入映射,輸出映射)
難點:對SQL語法及數據庫的瞭解需要多一些。
應用場景:
        適用於需求變化較多的項目,比如:互聯網項目。
        
SqlSession的使用範圍
SqlSessionFactoryBuilder
    將SqlSessionFactoryBuilder當成一個工具類使用即可,不需要使用單例管理SqlSessionFactoryBuilder
    在需要創建SqlSessionFactory的時候,只需要new一次SqlSessionFactoryBuilder即可。
SqlSessionFactory
    通過SqlSessionFactory創建SqlSession,使用單例模式管理SqlSessionFactory(工廠一旦創建,使用一個示例)
    將來mybatis和spring整合後,使用單例模式管理SqlSessionFactory
SqlSession
    SqlSession是一個面向用戶(程序員)的接口
    SqlSession中提供了很多操作數據庫的方法,例如:selectOne,selectList
    SqlSession是線程不安全的,在SqlSession的實現類中除了有接口中的方法,還有數據域的屬性
    SqlSession最佳的應用場合在方法體內,定義成局部變量

原始DAO開發方法(需要自己寫DAO接口和實現類)
    需要向DAO實現類注入SqlSessionFactory
    在方法體內通過工廠創建SqlSession

總結問題:
    1.DAO接口實現類方法中存在大量的模版方法,設想能否將這些代碼提取出來
    2.在調用sqlSession方法時將statement的id硬編碼了(寫死了)
    3.在調用sqlSession方法時傳入的變量,由於sqlSession方法使用泛型,
        即使變量類型傳入錯誤,在編譯階段也不會報錯,不利於程序員開發
Mapper代理方法
    1.程序員需要編寫mapper.xml文件
    2.程序員需要編寫Mapper接口,需要遵循一些開發規範
        MyBatis就可以自動的將生成mapper接口實現類的代理對象
開發規範:
1.在mapper.xml中namespace等於mapper接口的地址
2.mapper.java接口中的方法名和mapper.xml中的statement的id一致
3.mapper.java接口中的方法的輸入參數類型和和mapper.xml中的statement的parameterType的數據類型一致
4.mapper.java接口中的方法的輸出參數類型和和mapper.xml中的statement的resultType的數據類型一致

問題總結:
代理對象內部調用selectOne或selectList
    如果mapper方法返回單個pojo對象,代理對象內部通過selectOne查詢數據庫
    如果mapper方法返回pojo對象的集合,代理對象內部通過selectList查詢數據庫
mapper接口方法參數只能有一個是否影響系統開發
    系統框架中,DAO層代碼一定是被業務層共用的。
    即使mapper接口只有一個參數,可以使用包裝類型的pojo滿足不通的業務方法的需求
    【注意】
    持久層方法的參數可以使用包裝類型(map...),service方法中建議不要使用包裝類型(不利於業務層的維護和擴展)


MyBatis的全局配置文件SqlMapConfig.xml的相關配置如下:
properties(屬性)
    將數據庫鏈接參數單獨配置在db.properties中,只需要在SqlMapConfig.xml中加載db.properties的屬性值
    在SqlMapConfig.xml中就不需要對數據庫鏈接參數硬編碼
    將數據庫的鏈接參數db.properties中,原因:方便對參數進行統一管理,其他xml可以引用db.properties
    【注意】:MyBatis將按照下面的順序來加載屬性
                        1.在properties元素體內定義的屬性首先被讀取
                        2.然後會讀取properties元素中resource或url加載的屬性,它會覆蓋已讀取的同名屬性
                        3.最後讀取parameterType傳遞的屬性,它會覆蓋已讀取的同名屬性
                        因此,通過parameterType傳遞的屬性優先級最高,其次是resource或url加載的屬性,
                        最後是properties元素體內定義的屬性
    建議:不要在properties元素體內添加任何屬性值,只將屬性值定義在properties文件中
                在properties文件中定義的屬性名要有一定的特殊性,如:xxx.xxx.xxx
    
settings(全局配置參數)
    MyBatis框架在運行時可以調整一些運行參數,比如:二級緩存,延遲加載等等
    
typeAliases(類型別名)*
【MyBatis默認支持一下別名】
    別名                映射的類型
    _byte                    byte
    _long                    long
    _short              short
    _int                    int
    _integer            int
    _double                double
    _flaot                float
    _boolean            boolean
    string                String
    byte                    Byte
    long                    Long
    short                    Short
    int                        Integer
    integer                Integer
    double                Double
    float                    Float
    boolean                Boolean
    date                    Date
    decimal                BigDecimal
    bigdecimal        BigDecimal
    
typeHandlers(類型處理器)
    MyBatis中通過typeHandlers完成jdbc類型和java類型的轉換
    通常情況下,MyBatis提供的類型處理器滿足日常需要,不需要自定義
    
objectFactory(對象工廠)
plugins(插件)
enviornments(環境集合屬性對象)
    enviornment(環境子屬性對象)
        transcationManager(事務管理)
        dataSource(數據源)
mappers(映射器)
    通過resource方法加載單一映射文件
    <mapper resource="sqlmap/User.xml"/>
    通過url加載本地文件系統中的映射文件
    <mapper url="file:///D:\xxx\xx\xxx.xml"/>
    通過mapper接口加載
    <mapper class=""/>
    
    
MyBatis的輸入映射和輸出映射
輸入映射
    通過parameterType指定輸入參數的數據類型
    數據類型可以是簡單類型,HashMap,pojo類型
    
    pojo包裝對象
    
    
輸出映射
    使用resultType進行輸出映射,只有在查詢出來的列名和pojo中的屬性名一致,該列纔可以映射成功
    如果查詢出來的列名和pojo中的屬性名全部不一致,則返回中不會創建pojo對象
    只要查詢出來的列名和pojo中的屬性名有一個一致,就會創建pojo對象

    resultType還可以輸出簡單的數據類型(在查詢結果只有一行且只有一列時)
    
    輸出pojo對象
    輸出pojo對象的列表
    不管是輸出的pojo單個對象還是一個pojo對象列表,在mapper.xml中resultType指定的類型是一樣的
    在mapper.java中指定的方法返回值類型不一樣
    
    生成的動態代理對象中是根據mapper方法的返回值類型確定
    是調用selectOne(返回單個對象時調用)
    還是selectList(返回集合對象時調用)

    resultType還可以輸出HashMap的類型
    示例:List<HashMap<Pojo>>
    map中的key就是列名
    map中的value就是值
    
    
    MyBatis中使用resultMap完成高級輸出結果映射
    
    如果查詢出來的列名和pojo的屬性名不一致,通過定義一個resultMap對列名和pojo屬性名做一個映射關係
    
    resultType必須列名和pojo對象的屬性名一致才能輸出
    resultMap則可以在列名和pojo對象的屬性名之間建立對應關係後,就可以輸出


MyBatis高級映射(一對一,一對多,多對一,多對多)

    使用resultType實現(簡單)【無法實現延遲加載】
    
    使用resultMap實現(稍微複雜一點)【可以實現延遲加載】

    association完成一對一關聯映射查詢
    
    collection完成一對多關聯映射集合對象
    
resultMap總結
作用:將關聯查詢信息映射到一個pojo對象中
場合:爲了方便查詢關聯信息可以是用association將關聯訂單信息映射爲用戶對象的pojo屬性中,比如:查詢訂單及關聯用戶信息
            使用resultType無法將查詢解僱哦影視到pojo對象的pojo屬性中,根據對結果集查詢遍歷的需要選擇使用resultType還是resultMap
collection
作用:將關聯查詢信息映射到一個list集合中
場合:爲了方便查詢關聯信息可以使用collection將關聯信息映射到list集合中
            比如:查詢用戶權限範圍模塊及模塊下的菜單(一級+二級菜單)
                        可以使用collection將模塊映射到模塊list中,將菜單列表映射到模塊對象的菜單list屬性中
                        這樣做的目的是方便對查詢結果集進行遍歷
                        如果使用resultType無法將查詢結果映射到list集合中
                        
延遲加載
1.什麼是延遲加載
        延遲加載:先從單表查詢,需要時再關聯表去關聯查詢,大大提高數據庫性能,
                            因爲產線單表要比關聯查詢多張錶速度快
2.使用collection和association實現延遲加載

MyBatis的緩存


                                                                                            


一級緩存是sqlSession界別的緩存。在操作數據庫的時候需要構造sqlSession對象,
在該對象中有一個數據結構(HashMap)用於存儲緩存數據。
【注意】:不通的sqlSession直接的緩存數據區域(HashMap)是互不影響的


二級緩存是Mapper級別的緩存,多個sqlSession去操作同一個Mapper的SQL語句,
多個sqlSession操作數據庫得到的數據會存在二級緩存區域,即多個sqlSession可以共用二級緩存
【注意】:二級緩存是跨sqlSession的。


一級緩存的工作原理
示例:第一次發起查詢用戶id爲1的用戶信息,MyBatis會先去緩存中找是否有id爲1的用戶信息,
            如果沒有,則從數據庫查詢用戶信息。得到用戶信息後,將用戶信息存儲到一級緩存中。
            
            如果在sqlSession去執行commit操作(insert,update,delete),MyBatis會清空sqlSession中的一級緩存
            這樣做的目的是爲了讓緩存中存儲的是最新的數據,避免髒讀(舊數據)
            
            第二次發起查詢用戶id爲1的用戶信息,先去緩存中找是否有id爲1的用戶信息,緩存中有,
            則直接從緩存中獲取用戶信息
            
MyBatis默認支持一級緩存,不需要在配置文件中配置

一級緩存的使用
        在實際開發中,是將MyBatis和Spring進行整合開發,事務控制是在Service中
        一個Service方法包括很多Mapper方法的調用
        如果是執行兩次Service調用查詢相同的用戶信息,這時是不走一級緩存的
        【原因】:因爲Service方法結束,sqlSession就會關閉,一級緩存就會清空

二級緩存的使用
        在實際開發中,首先要將MyBatis的二級緩存開啓(默認不開啓)
        二級緩存與一級緩存的工作原理基本一樣
        區別在於:二級緩存的作用範圍更大,多個sqlSession可以共享一個UserMapper的二級緩存區域
        各個Mapper會有各自的二級緩存區域,緩存的區域是按照namespace劃分的。
        如果兩個Mapper的namespace相同,那麼這兩個Mapper所執行的sql將會存在同一個二級緩存區域


useCache參數:
        使用useCache來禁用二級緩存
        使用場景:useCache針對每次查詢都需要更新的數據SQL,要設置成useCache="false"
flushCache參數
        使用flushCache來清空當前namespace下的二級緩存即:flushCache="true"
        一般清空下,執行完commit的相關操作,都需要刷新相關緩存,flushCache="true"就表示刷新緩存
        這樣就可以避免數據庫髒讀

MyBatis和第三方緩存框架整合

整合方法:MyBatis提供了一個cache接口,如果要實現自己的緩存邏輯,只要實現cache接口開發即可。
例如:MyBatis和Ehcache整合,MyBatis和Ehcache整合包中就有對MyBatis的cache接口的實現
            MyBatis默認實現的cache類叫:PerpetualCache
            <cache/>標籤中的type屬性就是指定cache接口的實現類型
            若要和Ehcache整合,需要配置type爲Ehcache實現cache接口的實現類

二級緩存的應用場景
        對於訪問多的查詢請求並且用戶對查詢結果實時性要求不高,此時可採用MyBatis的二級緩存
                來降低數據庫訪問量,提高訪問速度
        業務應用場景:耗時較高的統計分析SQL,如果查詢昨天的消費清空,上個月的各種產品的銷售清空
        實現方法:通過設置刷新的間隔時間(flushInterval),由MyBatis每隔一段時間自動清空緩存
                根據數據編號頻率設置緩存的刷新時間,比如設置爲30分鐘,60分鐘,24小時等等
                
二級緩存使用的侷限性
        MyBatis二級緩存對細粒度的數據級別的緩存實現的不好
        比如:對商品信息進行緩存,由於商品信息查詢訪問量大,但要求用戶每次都能查詢最新的商品信息
                    此時如果使用MyBatis的二級緩存就無法實現當一個商品變化時只刷新該商品的緩存信息
                    而不刷新其他商品的信息,因爲MyBatis的二級緩存區域以Mapper爲單位來劃分
                    當一個商品信息變化會將所有商品信息的緩存數據全部清空。
                    解決此類問題需要在業務層根據需求對數據有針對性的做緩存處理





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章