Mybatis

一、JDBC弊端

  1. 重復(fù)創(chuàng)建鏈接和釋放鏈接,造成資源浪費(fèi)。解決方式:使用連接池
  2. 出現(xiàn)硬編碼,體現(xiàn)在數(shù)據(jù)庫驅(qū)動(dòng),url、用戶名密碼、sql。解決方式:使用配置文件
  3. 結(jié)果獲取不方便。解決方式:把結(jié)果放到一個(gè)POJO中

二、Mybatis的介紹

MyBatis 本是apache的一個(gè)開源項(xiàng)目iBatis,2010年這個(gè)項(xiàng)目由apache software foundation 遷移到了google code,并且改名為MyBatis 。2013年11月遷移到Github。iBATIS一詞來源于“internet”和“abatis”的組合,是一個(gè)基于Java的持久層框架。iBATIS提供的持久層框架包括SQL Maps和Data Access Objects(DAOs)。當(dāng)前,最新版本是MyBatis 3.5.1 ,其發(fā)布時(shí)間是2019年4月8日。

MyBatis 是一款支持普通 SQL查詢,存儲(chǔ)過程和高級(jí)映射的優(yōu)秀持久層框架。MyBatis 消除了幾乎所有的JDBC代碼和參數(shù)的手工設(shè)置以及結(jié)果集的檢索。MyBatis 使用簡單的 XML或注解用于配置和原始映射,將接口和 Java 的POJOs(Plain Ordinary Java Objects,普通的 Java對(duì)象)映射成數(shù)據(jù)庫中的記錄。

每個(gè)MyBatis應(yīng)用程序主要都是使用SqlSessionFactory實(shí)例的,一個(gè)SqlSessionFactory實(shí)例可以通過SqlSessionFactoryBuilder獲得。SqlSessionFactoryBuilder可以從一個(gè)xml配置文件或者一個(gè)預(yù)定義的配置類的實(shí)例獲得。

用xml文件構(gòu)建SqlSessionFactory實(shí)例是非常簡單的事情。推薦在這個(gè)配置中使用類路徑資源(classpath resource),但你可以使用任何Reader實(shí)例,包括用文件路徑或file://開頭的url創(chuàng)建的實(shí)例。MyBatis有一個(gè)實(shí)用類----Resources,它有很多方法,可以方便地從類路徑及其它位置加載資源。

三、Mybatis架構(gòu)

Mybatis架構(gòu).jpg
  1. mybatis配置 SqlMapConfig.xml,此文件作為mybatis的全局配置文件,配置了mybatis的運(yùn)行環(huán)境等信息。mapper.xml文件即sql映射文件,文件中配置了操作數(shù)據(jù)庫的sql語句。此文件需要在SqlMapConfig.xml中加載。
  2. 通過mybatis環(huán)境等配置信息構(gòu)造SqlSessionFactory即會(huì)話工廠。
  3. 由會(huì)話工廠創(chuàng)建sqlSession即會(huì)話,操作數(shù)據(jù)庫需要通過sqlSession進(jìn)行。
  4. mybatis底層自定義了Executor執(zhí)行器接口操作數(shù)據(jù)庫,Executor接口有兩個(gè)實(shí)現(xiàn),一個(gè)是基本執(zhí)行器、一個(gè)是緩存執(zhí)行器。
  5. Mapped Statement也是mybatis一個(gè)底層封裝對(duì)象,它包裝了mybatis配置信息及sql映射信息等。mapper.xml文件中一個(gè)sql對(duì)應(yīng)一個(gè)Mapped Statement對(duì)象,sql的id即是Mapped statement的id。
  6. Mapped Statement對(duì)sql執(zhí)行輸入?yún)?shù)進(jìn)行定義,包括HashMap、基本類型、pojo,Executor通過Mapped Statement在執(zhí)行sql前將輸入的java對(duì)象映射至sql中,輸入?yún)?shù)映射就是jdbc編程中對(duì)preparedStatement設(shè)置參數(shù)。
  • 輸入映射(傳入的參數(shù))
    支持的數(shù)據(jù)類型:
    基本數(shù)據(jù)類型:基礎(chǔ)類型以及包裝類、String
    POJO
    Map
    包裝的POJO:一個(gè)pojo中有pojo屬性
  1. Mapped Statement對(duì)sql執(zhí)行輸出結(jié)果進(jìn)行定義,包括HashMap、基本類型、pojo,Executor通過Mapped Statement在執(zhí)行sql后將輸出結(jié)果映射至java對(duì)象中,輸出結(jié)果映射過程相當(dāng)于jdbc編程中對(duì)結(jié)果的解析處理過程。
  • 輸出映射(產(chǎn)生的結(jié)果類型)
    基本數(shù)據(jù)類型:基礎(chǔ)類型以及包裝類、String
    POJO
    Map
    List

四、MyBatis xml配置文件層次結(jié)構(gòu)

MyBatis配置文件層次結(jié)構(gòu).jpg

properties元素

properties是一個(gè)配置屬性的元素,讓開發(fā)者能在配置文件的上下文中使用它,MyBatis提供3種配置方式:

  1. property子元素。
  2. properties配置文件。
  3. SqlSessionFactoryBuilder使用Properties文件構(gòu)建。

property子元素

 <property name="driver" value="com.mysql.jdbc.Driver"/>

properties配置文件
一般會(huì)使用一個(gè)單獨(dú)的properties配置文件來配置屬性值,以方便在多個(gè)配置文件中重復(fù)使用它們,也方便日后維護(hù)和隨時(shí)修改??梢酝ㄟ^${key}的形式,取出在配置文件中配置的值。

<configuration>
    <!-- 引入配置文件 -->
    <properties resource="datasource.properties"/>

    <environments default="dev">
        <environment id="dev">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <!-- 使用配置文件中的屬性 -->
                <property name="driver" value="${driver}"/>
                <property name="url" value="${url}"/>
                <property name="username" value="${username}"/>
            </dataSource>
        </environment>
    </environments>
</configuration>

SqlSessionFactoryBuilder使用Properties文件構(gòu)建
出于安全考慮,properties配置文件中的賬號(hào)密碼等元素可能是加密的,這個(gè)時(shí)候就需要對(duì)加密的元素進(jìn)行處理。

    public static void func() throws Exception {
        Properties properties = new Properties();
        properties.load(Resources.getResourceAsStream("datasource.properties"));
        // 對(duì)原賬號(hào)密碼解密
        properties.setProperty("username", decode(properties.getProperty("username")));
        properties.setProperty("password", decode(properties.getProperty("password")));

        InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
        // SqlSessionFactoryBuilder可以使用一個(gè)InputStream和一個(gè)Properties構(gòu)建SqlSessionFactory
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is, properties);
    }

三種方式的優(yōu)先級(jí)
MyBatis支持的3種配置方式可能同時(shí)出現(xiàn),并且屬性還會(huì)重復(fù)配置,MyBatis將按照下面的順序來加載:

  1. 在properties元素體內(nèi)指定的屬性首先被讀取。
  2. 根據(jù) properties元素中的resource屬性讀取類路徑下屬性文件,或者根據(jù)url屬性指定的路徑讀取屬性文件,并覆蓋已讀取的同名屬性。
  3. 讀取作為build()方法參數(shù)傳遞的屬性,并覆蓋已讀取的同名屬性。

因此,通過build()方法參數(shù)傳遞的屬性具有最高優(yōu)先級(jí),resource/url屬性中指定的配置文件次之,最低優(yōu)先級(jí)的是 properties屬性中指定的屬性。因此,我們盡量不要使用混合的方式來定義配置,首選的方式是使用properties文件。

五、environments環(huán)境變量

配置環(huán)境可以注冊(cè)多個(gè)環(huán)境,每一個(gè)環(huán)境分為兩大部分:一個(gè)是數(shù)據(jù)庫源(dataSource)的配置,另外一個(gè)是數(shù)據(jù)庫事務(wù)(transactionManager)的配置。

    <environments default="dev">
        <environment id="dev">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="${driver}"/>
                <property name="url" value="${url}"/>
                <property name="username" value="${username}"/>
            </dataSource>
        </environment>
    </environments>
  1. default:表示默認(rèn)使用哪個(gè)數(shù)據(jù)源
  2. id:表示數(shù)據(jù)源的名稱
  3. transactionManager的事務(wù)類型type一共有三種:JDBC,采用JDBC方式管理事務(wù),獨(dú)立編碼中我們常常使用;MANAGED,采用容器方式管理事務(wù),在JNDI數(shù)據(jù)源中常用;自定義,由使用者自定義數(shù)據(jù)庫事務(wù)管理辦法,適用于特殊應(yīng)用。
  4. property元素配置數(shù)據(jù)源的各類屬性
  5. dataSource的type屬性是提供我們對(duì)數(shù)據(jù)厙連接方式的配置:UNPOOLED(非連接池?cái)?shù)據(jù)庫)、POOLED(連接池?cái)?shù)據(jù)庫)、JNDI(JNDI數(shù)據(jù)源)、自定義數(shù)據(jù)源。

六、數(shù)據(jù)源

MyBatis內(nèi)部為我們提供了3種數(shù)據(jù)源的實(shí)現(xiàn)方式:

  • UNPOOLED,使用org.apache.ibatis.datasource.unpooled.UnpooledDataSource實(shí)現(xiàn)。
  • POOLED,使用org.apache.ibatis.datasource.pooled.PooledDataSource實(shí)現(xiàn)。
  • JNDI,使用org.apache.ibatis.datasource.jndi.JndiDataSourceFactory實(shí)現(xiàn)。

七、數(shù)據(jù)庫事務(wù)

數(shù)據(jù)庫事務(wù)是交由SqlSession去控制的,我們可以通過SqlSession提交或者回滾。在大部分的工作環(huán)境下,我們都會(huì)使用 Spring框架來控制它。

八、Mybatis解決jdbc編程的問題

  1. 數(shù)據(jù)庫鏈接創(chuàng)建、釋放頻繁造成系統(tǒng)資源浪費(fèi)從而影響系統(tǒng)性能,如果使用數(shù)據(jù)庫鏈接池可解決此問題。
    解決:在SqlMapConfig.xml中配置數(shù)據(jù)鏈接池,使用連接池管理數(shù)據(jù)庫鏈接。
  2. Sql語句寫在代碼中造成代碼不易維護(hù),實(shí)際應(yīng)用sql變化的可能較大,sql變動(dòng)需要改變java代碼。
    解決:將Sql語句配置在XXXXmapper.xml文件中與java代碼分離。
  3. 向sql語句傳參數(shù)麻煩,因?yàn)閟ql語句的where條件不一定,可能多也可能少,占位符需要和參數(shù)一一對(duì)應(yīng)。
    解決:Mybatis自動(dòng)將java對(duì)象映射至sql語句,通過statement中的parameterType定義輸入?yún)?shù)的類型。
  4. 對(duì)結(jié)果集解析麻煩,sql變化導(dǎo)致解析代碼變化,且解析前需要遍歷,如果能將數(shù)據(jù)庫記錄封裝成pojo對(duì)象解析比較方便。
    解決:Mybatis自動(dòng)將sql執(zhí)行結(jié)果映射至java對(duì)象,通過statement中的resultType定義輸出結(jié)果的類型。
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

  • 1. 簡介 1.1 什么是 MyBatis ? MyBatis 是支持定制化 SQL、存儲(chǔ)過程以及高級(jí)映射的優(yōu)秀的...
    笨鳥慢飛閱讀 6,284評(píng)論 0 4
  • 1. Mybatis的介紹 MyBatis 本是apache的一個(gè)開源項(xiàng)目iBatis, 2010年這個(gè)項(xiàng)目由ap...
    itzhouq的筆記閱讀 762評(píng)論 0 5
  • MyBatis 理論篇 [TOC] 什么是MyBatis ?MyBatis是支持普通SQL查詢,存儲(chǔ)過程和高級(jí)映射...
    有_味閱讀 3,186評(píng)論 0 26
  • 之前在面試工作的時(shí)候,我當(dāng)時(shí)用的是hibernate,但是現(xiàn)在互聯(lián)網(wǎng)項(xiàng)目并發(fā)量大,一般都會(huì)選擇使用Mybatis,...
    唐偉耀閱讀 604評(píng)論 1 0
  • 天意熏熏風(fēng)草樹,吾獨(dú)離群望兵步。 閑處該時(shí)逢稚子,攜予浦英付我笑。 一笑當(dāng)思?jí)羰?,十年吾尚貪青蟲。 青蟲季季尤可...
    柳尋川閱讀 188評(píng)論 0 2

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