深入理解MyBatis--認識Mybatis

一直想探究Mybatis的內部實現,之前自己抽空看了下源碼,當時把核心的代碼流程都能走一遍,感覺似懂非懂的懂了,過了一段時間呢又沒啥收穫了,還是缺乏理解深度。最近有時間買了本《Mybatis技術內幕》,站在大牛的肩膀,更好的理解Mybatis。
在開始認識Mybatis之前,得先了解一些基本概念

基本概念


JDBC

  • Java和數據庫交互的統一API
  • 兩部分:Java API 、數據庫驅動API
  • JDBC操作步驟:
    • 打開連接—數據庫驅動 :URL 用戶名 密碼等連接信息
    • DriverManager
    • Statement
    • ResultSet
    • 轉JavaBean
    • 關閉連接
  • 數據源
  • 結果緩存
  • 數據庫連接池

ORM

  • Object Relational Mapping 對象關係映射
  • java 文件 <—> 映射配置文件 <—> 數據庫
  • 常見ORM框架
    Hibernate
    • hbm.xml配置
    • java 對象 OneToMany、OneToOne、ManyToMany關係,應用層對象維護主外鍵關係
    • HQL語句,面向對象的思維,屏蔽掉底層數據庫的差異。
    • 沒有代碼侵入性,業務代碼不需要繼承或實現Hibernate任何類和接口
    • 提供一級和二級緩存,降低數據庫壓力
    • 根據對象模型自動建表
    • 缺點:
      • 數據庫有自身的組織方式,hibernate生成的sql不一定是最優性能,並且很難修改生成的SQL
      • 數據量大,結構複雜的表,生成的SQL複雜,索引不能正確使用,導致大量慢查詢,不適合大數據量,高併發,低延遲的場景
      • 對批處理的支持並不友好,會影響部分性能
    JPA
    • EJB3.0中的持久化部分的規範,並沒有提供實現。
    Spring JDBC
    • 本質是個使用模板方法封裝了原生JDBC,並不算ORM框架
    • 封裝Template
    • 提供Callback ,供處理ResultSet
    MyBatis
    • 屏蔽原生JDBC,配置文件實現ResultSet與Java對象映射
    • 輕量級,可控性高,半自動化編寫SQL語句,更加靈活,提高系統性能。
    Hibernate、Mybatis和Spring JDBC三者比較
    • Hibernate生成SQL語句,Spring JDBC和Mybaits使用原生SQL
    • Mybatis 和 Hibernate 使用二級緩存
    • Hibernate屏蔽數據方言,Spring JDBC和Mybaits未支持
    • Hibernate和Mybatis 通過XML配置,Spring JDBC通過Template 和Callback 方式實現
    • 量級重到輕:Hibernate --> Mybatis --> Spring JDBC

Mybatis整體架構


整體架構分爲三層:基礎支持層、核心處理層和接口層
在這裏插入圖片描述

基礎支持層

  • 反射模塊:對Java原生的反射進行良好封裝,提供簡潔易用的API,供上層使用。並進行了優化,提高反射性能
  • 類型轉換模塊:別名機制;Java類型與JDBC類型轉換
  • 日誌模塊:提供詳細的日誌輸出信息,還能夠集成多種日誌框架。日誌模塊主要功能集成第三方日誌框架
  • 資源加載模塊:對類加載器的封裝,加載類文件,資源文件
  • 解析器模塊:XPath的封裝,解析配置文件提供支持;處理動態SQL語句的佔位符提供支持
  • 數據源模塊:自身提供數據源模塊,也提供了第三方數據源集成的接口
  • 事務管理:自身提供事務接口和簡單實現,也與Spring框架集成,由Spring框架管理事務
  • 緩存模塊:Mybatis 一級二級緩存都依賴緩存模塊實現,利用的是JVM堆內存。
  • Binding模塊:將用戶自定義的Mapper接口和映射配置文件關聯起來,系統可通過Mapper接口中的方法執行對應的SQL語句,完成數據庫操作。

核心處理層

實現了MyBatis的核心處理流程,包括初始化及完成一次數據庫操作涉及的全部流程。

  • 配置解析:解析mybatis-config.xml文件、映射配置文件及Mapper接口註解信息,保存Configuration對象中,利用Configuration對象創建SqlSessionFactory對象等。
  • SQL解析與scripting模塊:提供動態SQL語句功能,對應各種節點。例如、等。scripting模塊接受用戶傳參,佔位符解析綁定入參。
  • SQL執行:Executor(提供事務管理,維護一、二級緩存)、StatementHandler、ParameterHandler和ResultSetHandler等。
    在這裏插入圖片描述
  • 插件:提供插件接口,供添加用戶自定義插件,可以改變Mybatis默認行爲。例如:可以攔截SQL語句並對其重寫。

接口層

暴露給應用程序調用的API,核心是SqlSession接口。

使用Mybatis的示例代碼


mybatis-config.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">

<!-- 官方完整的配置 -->
<configuration>
    <!-- properties 指定properties配置文件,指定數據庫連接配置文件 -->
    <properties resource="database.properties"/>

    <!-- settings配置:這是 MyBatis 中極爲重要的調整設置,它們會改變 MyBatis 的運行時行爲。一般使用只需保持默認值。 -->
    <settings>
        <!-- 全局地開啓或關閉配置文件中的所有映射器已經配置的任何緩存。默認true -->
        <setting name="cacheEnabled" value="true"/>
        <!--延遲加載的全局開關。當開啓時,所有關聯對象都會延遲加載。特定關聯關係中可通過設置fetchType屬性來覆蓋該項的開關狀態。默認false-->
        <setting name="lazyLoadingEnabled" value="false"/>
        <!--當開啓時,任何方法的調用都會加載該對象的所有屬性。否則,每個屬性會按需加載(參考lazyLoadTriggerMethods).默認值	false (true in ≤3.4.1)-->
        <setting name="aggressiveLazyLoading" value="false"/>
        <!-- 是否允許單一語句返回多結果集(需要兼容驅動)。 默認true-->
        <setting name="multipleResultSetsEnabled" value="true"/>
        <!-- 使用列標籤代替列名。不同的驅動在這方面會有不同的表現, 具體可參考相關驅動文檔或通過測試這兩種不同的模式來觀察所用驅動的結果。 默認值true-->
        <setting name="useColumnLabel" value="true"/>
        <!-- 允許 JDBC 支持自動生成主鍵,需要驅動兼容。 如果設置爲 true 則這個設置強制使用自動生成主鍵,儘管一些驅動不能兼容但仍可正常工作(比如 Derby)。默認false-->
        <setting name="useGeneratedKeys" value="false"/>
        <!--指定 MyBatis 應如何自動映射列到字段或屬性。 NONE 表示取消自動映射;PARTIAL 只會自動映射沒有定義嵌套結果集映射的結果集。 FULL 會自動映射任意複雜的結果集(無論是否嵌套)。默認爲PARTIAL-->
        <setting name="autoMappingBehavior" value="PARTIAL"/>
        <!--指定發現自動映射目標未知列(或者未知屬性類型)的行爲。-->
        <!--
            NONE: 不做任何反應
            WARNING: 輸出提醒日誌 ('org.apache.ibatis.session.AutoMappingUnknownColumnBehavior' 的日誌等級必須設置爲 WARN)
            FAILING: 映射失敗 (拋出 SqlSessionException)
        -->
        <setting name="autoMappingUnknownColumnBehavior" value="WARNING"/>
        <!-- 配置默認的執行器。SIMPLE 就是普通的執行器;REUSE 執行器會重用預處理語句(prepared statements); BATCH 執行器將重用語句並執行批量更新。默認SIMPLE -->
        <setting name="defaultExecutorType" value="SIMPLE"/>
        <!--設置超時時間,它決定驅動等待數據庫響應的秒數。設置任意正值,沒有默認值-->
        <setting name="defaultStatementTimeout" value="25"/>
        <!--爲驅動的結果集獲取數量(fetchSize)設置一個提示值。此參數只可以在查詢設置中被覆蓋。設置任意正值,沒有默認值-->
        <setting name="defaultFetchSize" value="100"/>
        <!--允許在嵌套語句中使用分頁(RowBounds)。如果允許使用則設置爲false。 默認false-->
        <setting name="safeRowBoundsEnabled" value="false"/>
        <!--允許在嵌套語句中使用分頁(ResultHandler)。如果允許使用則設置爲false。默認true-->
        <setting name="safeResultHandlerEnabled" value="true"/>
        <!--是否開啓自動駝峯命名規則(camel case)映射,即從經典數據庫列名 A_COLUMN 到經典 Java 屬性名 aColumn 的類似映射。默認爲false-->
        <setting name="mapUnderscoreToCamelCase" value="false"/>
        <!--MyBatis 利用本地緩存機制(Local Cache)防止循環引用(circular references)和加速重複嵌套查詢。 默認值爲 SESSION,這種情況下會緩存一個會話中執行的所有查詢。
        若設置值爲 STATEMENT,本地會話僅用在語句執行上,對相同 SqlSession 的不同調用將不會共享數據。-->
        <setting name="localCacheScope" value="SESSION"/>
        <!--當沒有爲參數提供特定的 JDBC 類型時,爲空值指定 JDBC 類型。 某些驅動需要指定列的 JDBC 類型,多數情況直接用一般類型即可,比如 NULL、VARCHAR 或 OTHER。默認值OTHER-->
        <setting name="jdbcTypeForNull" value="OTHER"/>
        <!--指定哪個對象的方法觸發一次延遲加載。用逗號分隔的方法列表。默認值:equals,clone,hashCode,toString -->
        <setting name="lazyLoadTriggerMethods" value="equals,clone,hashCode,toString"/>
    </settings>

    <!--聲明類型的別名,可以將一個類,指定一個簡單的名字,後面直接代替-->
    <typeAliases>
        <typeAlias alias="String" type="java.lang.String"/>
        <typeAlias alias="Dict" type="ybs.mybatis.model.Dict"/>
    </typeAliases>

    <!--指定一個類型處理器,mybatis默認提供了基本類型的類型匹配器,除非不夠用,自己可以自定義。-->
    <typeHandlers>
        <typeHandler handler="ExampleTypeHandler"/>
    </typeHandlers>

    <!--
        MyBatis 每次創建結果對象的新實例時,它都會使用一個對象工廠(ObjectFactory)實例來完成。
        默認的對象工廠需要做的僅僅是實例化目標類,要麼通過默認構造方法,要麼在參數映射存在的時候通過參數構造方法來實例化。 如果想覆蓋對象工廠的默認行爲,則可以通過創建自己的對象工廠來實現
        繼承DefaultObjectFactory來擴展
     -->
    <objectFactory type="ExampleObjectFactory">
        <property name="someProperty" value="100"/>
    </objectFactory>

    <!--寫一些插件,來攔截加入一些功能:自定義插件類implements Interceptor-->
    <plugins>
        <plugin interceptor="ExamplePlugin">
            <property name="someProperty" value="100"/>
        </plugin>
    </plugins>

    <!--配置環境-->
    <!--
        儘管可以配置多個環境,每個 SqlSessionFactory 實例只能選擇其一
        如果你想連接兩個數據庫,就需要創建兩個 SqlSessionFactory 實例,每個數據庫對應一個。而如果是三個數據庫,就需要三個實例
        在初始化SqlSessionFactory時進行指定哪個environment
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader, environment);
        environment 參數爲String,environment的id值
    -->
    <environments default="development">
        <environment id="development">
            <!--
                事務管理器
                在 MyBatis 中有兩種類型的事務管理器(也就是 type=”[JDBC|MANAGED]”)
                JDBC – 這個配置就是直接使用了 JDBC 的提交和回滾設置,它依賴於從數據源得到的連接來管理事務作用域。
                MANAGED – 這個配置幾乎沒做什麼。它從來不提交或回滾一個連接,而是讓容器來管理事務的整個生命週期(比如 JEE 應用服務器的上下文)。
                          默認情況下它會關閉連接,然而一些容器並不希望這樣,因此需要將 closeConnection 屬性設置爲 false 來阻止它默認的關閉行爲。

                你可以使用 TransactionFactory 接口的實現類的完全限定名或類型別名代替它們。
             -->
            <!--如果你正在使用 Spring + MyBatis,則沒有必要配置事務管理器, 因爲 Spring 模塊會使用自帶的管理器來覆蓋前面的配置。-->
            <transactionManager type="JDBC"/>
            <!--
                配置數據庫連接、數據庫連接池
                有三種內建的數據源類型(也就是 type=”[UNPOOLED|POOLED|JNDI]”)
                UNPOOLED– 這個數據源的實現只是每次被請求時打開和關閉連接。雖然有點慢,但對於在數據庫連接可用性方面沒有太高要求的簡單應用程序來說,是一個很好的選擇。
                POOLED– 這種數據源的實現利用“池”的概念將 JDBC 連接對象組織起來,避免了創建新的連接實例時所必需的初始化和認證時間。 這是一種使得併發 Web 應用快速響應請求的流行處理方式。
                JNDI – 這個數據源的實現是爲了能在如 EJB 或應用服務器這類容器中使用,容器可以集中或在外部配置數據源,然後放置一個 JNDI 上下文的引用

                你可以通過實現接口 org.apache.ibatis.datasource.DataSourceFactory 來使用第三方數據源
            -->

            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://10.27.164.193:3306/cfsdb"/>
                <property name="username" value="devadmin"/>
                <property name="password" value="KTaDN9eMHY"/>
            </dataSource>
        </environment>
        <environment id="sit">
            <!-- 事務管理器 -->
            <transactionManager type="JDBC"/>
            <!-- 配置數據庫連接、數據庫連接池 -->
            <dataSource type="POOLED">
                <!--
                    property屬性可以利用佔位符號表示,利用property文件指定值。
                    SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader, properties);
                    Properties類型的參數
                -->
                <property name="driver" value="${driver}"/>
                <property name="url" value="${url}"/>
                <property name="username" value="${username}"/>
                <property name="password" value="${password}"/>
            </dataSource>
        </environment>
    </environments>


    <!--MyBatis 可以根據不同的數據庫廠商執行不同的語句,這種多廠商的支持是基於映射語句中的 databaseId 屬性。-->
    <databaseIdProvider type="DB_VENDOR">
        <property name="SQL Server" value="sqlserver"/>
        <property name="DB2" value="db2"/>
        <property name="Oracle" value="oracle"/>
    </databaseIdProvider>

    <!--指定sql資源路徑-->
    <mappers>
        <!-- 指定mapper下的包路徑。
        <package name="mapper" />
        -->
        <mapper resource="mapper/DictMapper.xml"/>
    </mappers>
</configuration>
Mapper.xml文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >

<!--完整的解釋mapper的配置項-->
<!--
cache – 給定命名空間的緩存配置。
cache-ref – 其他命名空間緩存配置的引用。
resultMap – 是最複雜也是最強大的元素,用來描述如何從數據庫結果集中來加載對象。
parameterMap – 已廢棄!老式風格的參數映射。內聯參數是首選,這個元素可能在將來被移除,這裏不會記錄。
sql – 可被其他語句引用的可重用語句塊。
insert – 映射插入語句
update – 映射更新語句
delete – 映射刪除語句
select – 映射查詢語句
-->


<!-- Namespaces 命名空間 :在之前版本的 MyBatis 中是可選的,這樣容易引起混淆因此毫無益處。
     現在命名空間則是必須的,且意於簡單地用更長的完全限定名來隔離語句。-->
<mapper>

    <!--字段映射實體-->
    <resultMap id="dictMap" type="ybs.mybatis.model.Dict" >
        <id column="ID" property="id" jdbcType="BIGINT" />
        <result column="NAME" property="name" jdbcType="VARCHAR" />
        <result column="DICT_CODE" property="dictCode" jdbcType="VARCHAR" />
        <result column="DICT_KEY" property="dictKey" jdbcType="VARCHAR" />
        <result column="DICT_VALUE" property="dictValue" jdbcType="VARCHAR" />
        <result column="DESCRIPTION" property="description" jdbcType="VARCHAR" />
        <result column="CREATOR" property="creator" jdbcType="BIGINT" />
        <result column="CREATED_TIME" property="createdTime" jdbcType="TIMESTAMP" />
        <result column="MODIFER" property="modifer" jdbcType="BIGINT" />
        <result column="MODIFIED_TIME" property="modifiedTime" jdbcType="TIMESTAMP" />
    </resultMap>

    <!--
        查詢語句,parameterType接受參數類型 resultType返回集合類型
        #{id} 個預處理語句參數,通過 JDBC,這樣的一個參數在 SQL 中會由一個“?”來標識
    -->
    <!--
        select標籤下,各種屬性
            id	在命名空間中唯一的標識符,可以被用來引用這條語句。
            parameterType	將會傳入這條語句的參數類的完全限定名或別名。這個屬性是可選的,因爲 MyBatis 可以通過 TypeHandler 推斷出具體傳入語句的參數,默認值爲 unset。
            parameterMap	這是引用外部 parameterMap 的已經被廢棄的方法。使用內聯參數映射和 parameterType 屬性。
            resultType	從這條語句中返回的期望類型的類的完全限定名或別名。注意如果是集合情形,那應該是集合可以包含的類型,而不能是集合本身。使用 resultType 或 resultMap,但不能同時使用。
            resultMap	外部 resultMap 的命名引用。結果集的映射是 MyBatis 最強大的特性,對其有一個很好的理解的話,許多複雜映射的情形都能迎刃而解。使用 resultMap 或 resultType,但不能同時使用。
            flushCache	將其設置爲 true,任何時候只要語句被調用,都會導致本地緩存和二級緩存都會被清空,默認值:false。
            useCache	將其設置爲 true,將會導致本條語句的結果被二級緩存,默認值:對 select 元素爲 true。
            timeout	這個設置是在拋出異常之前,驅動程序等待數據庫返回請求結果的秒數。默認值爲 unset(依賴驅動)。
            fetchSize	這是嘗試影響驅動程序每次批量返回的結果行數和這個設置值相等。默認值爲 unset(依賴驅動)。
            statementType	STATEMENT,PREPARED 或 CALLABLE 的一個。這會讓 MyBatis 分別使用 Statement,PreparedStatement 或 CallableStatement,默認值:PREPARED。
            resultSetType	FORWARD_ONLY,SCROLL_SENSITIVE 或 SCROLL_INSENSITIVE 中的一個,默認值爲 unset (依賴驅動)。
            databaseId	如果配置了 databaseIdProvider,MyBatis 會加載所有的不帶 databaseId 或匹配當前 databaseId 的語句;如果帶或者不帶的語句都有,則不帶的會被忽略。
            resultOrdered	這個設置僅針對嵌套結果 select 語句適用:如果爲 true,就是假設包含了嵌套結果集或是分組了,這樣的話當返回一個主結果行的時候,就不會發生有對前面結果集的引用的情況。這就使得在獲取嵌套的結果集的時候不至於導致內存不夠用。默認值:false。
            resultSets	這個設置僅對多結果集的情況適用,它將列出語句執行後返回的結果集並每個結果集給一個名稱,名稱是逗號分隔的。
    -->
    <select id="selectByPrimaryKey" parameterType="java.lang.Long" resultType="ybs.mybatis.model.Dict">
        select * from CF_DICT where id = #{id,jdbcType=BIGINT}
    </select>


    <!--
        insert/update/delete 各種屬性
            id	命名空間中的唯一標識符,可被用來代表這條語句。
            parameterType	將要傳入語句的參數的完全限定類名或別名。這個屬性是可選的,因爲 MyBatis 可以通過 TypeHandler 推斷出具體傳入語句的參數,默認值爲 unset。
            parameterMap	這是引用外部 parameterMap 的已經被廢棄的方法。使用內聯參數映射和 parameterType 屬性。
            flushCache	將其設置爲 true,任何時候只要語句被調用,都會導致本地緩存和二級緩存都會被清空,默認值:true(對應插入、更新和刪除語句)。
            timeout	這個設置是在拋出異常之前,驅動程序等待數據庫返回請求結果的秒數。默認值爲 unset(依賴驅動)。
            statementType	STATEMENT,PREPARED 或 CALLABLE 的一個。這會讓 MyBatis 分別使用 Statement,PreparedStatement 或 CallableStatement,默認值:PREPARED。
            useGeneratedKeys	(僅對 insert 和 update 有用)這會令 MyBatis 使用 JDBC 的 getGeneratedKeys 方法來取出由數據庫內部生成的主鍵(比如:像 MySQL 和 SQL Server 這樣的關係數據庫管理系統的自動遞增字段),默認值:false。
            keyProperty	(僅對 insert 和 update 有用)唯一標記一個屬性,MyBatis 會通過 getGeneratedKeys 的返回值或者通過 insert 語句的 selectKey 子元素設置它的鍵值,默認:unset。如果希望得到多個生成的列,也可以是逗號分隔的屬性名稱列表。
            keyColumn	(僅對 insert 和 update 有用)通過生成的鍵值設置表中的列名,這個設置僅在某些數據庫(像 PostgreSQL)是必須的,當主鍵列不是表中的第一列的時候需要設置。如果希望得到多個生成的列,也可以是逗號分隔的屬性名稱列表。
            databaseId	如果配置了 databaseIdProvider,MyBatis 會加載所有的不帶 databaseId 或匹配當前 databaseId 的語句;如果帶或者不帶的語句都有,則不帶的會被忽略。
    -->
    <insert
            id="insertAuthor"
            parameterType="domain.blog.Author"
            flushCache="true"
            statementType="PREPARED"
            keyProperty=""
            keyColumn=""
            useGeneratedKeys="true"
            timeout="20">
    </insert>

    <update
            id="updateAuthor"
            parameterType="domain.blog.Author"
            flushCache="true"
            statementType="PREPARED"
            timeout="20">
    </update>

    <delete
            id="deleteAuthor"
            parameterType="domain.blog.Author"
            flushCache="true"
            statementType="PREPARED"
            timeout="20">
    </delete>

    <!--這個元素可以被用來定義可重用的 SQL 代碼段,可以包含在其他語句中。相當於sql片段,可以供公用-->
    <sql id="userColumns"> ${alias}.id,${alias}.username,${alias}.password </sql>
    <!--試用sql的地方,利用include標籤
    <include refid="userColumns">
        <property name="prefix" value="Some"/>
        <property name="include_target" value="sometable"/>
    </include>
    -->

    <!--
        MyBatis 包含一個非常強大的查詢緩存特性,它可以非常方便地配置和定製。MyBatis 3 中的緩存實現的很多改進都已經實現了,使得它更加強大而且易於配置。
        默認情況下是沒有開啓緩存的,除了局部的 session 緩存,可以增強變現而且處理循環 依賴也是必須的。要開啓二級緩存,你需要在你的 SQL 映射文件中添加一行:
            映射語句文件中的所有 select 語句將會被緩存。
            映射語句文件中的所有 insert,update 和 delete 語句會刷新緩存。
            緩存會使用 Least Recently Used(LRU,最近最少使用的)算法來收回。
            根據時間表(比如 no Flush Interval,沒有刷新間隔), 緩存不會以任何時間順序 來刷新。
            緩存會存儲列表集合或對象(無論查詢方法返回什麼)的 1024 個引用。
            緩存會被視爲是 read/write(可讀/可寫)的緩存,意味着對象檢索不是共享的,而 且可以安全地被調用者修改,而不干擾其他調用者或線程所做的潛在修改。
    -->
    <cache/>

    <!--
    <cache
            可用的收回策略有: 默認是LRU
                LRU – 最近最少使用的:移除最長時間不被使用的對象。
                FIFO – 先進先出:按對象進入緩存的順序來移除它們。
                SOFT – 軟引用:移除基於垃圾回收器狀態和軟引用規則的對象。
                WEAK – 弱引用:更積極地移除基於垃圾收集器狀態和弱引用規則的對象
            eviction="FIFO"

            每隔 60 秒刷新;flushInterval(刷新間隔)可以被設置爲任意的正整數,而且它們代表一個合理的毫秒 形式的時間段。默認情況是不設置,也就是沒有刷新間隔,緩存僅僅調用語句時刷新。
            flushInterval="60000"

            存數結果對象或列表的 512 個引用。引用數目:可以被設置爲任意正整數,要記住你緩存的對象數目和你運行環境的 可用內存資源數目。默認值是 1024。
            size="512"

            返回的對象被認爲是隻讀的,因此在不同線程中的調用者之間修改它們會 導致衝突。
            只讀的緩存會給所有調用者返回緩存對象的相同實例。因此這些對象不能被修改。這提供了很重要的性能優勢。可讀寫的緩存會返回緩存對象的拷貝(通過序列化) 。這會慢一些,但是安全,因此默認是 false。
            readOnly="true"/>
    -->
</mapper>
Mapper接口
/**
 * 庫表操作類
 *
 * @author yanbin
 * @version 2018/3/29 11:14
 *
 **/
public interface DictMapper {

	/**
	 * 根據主鍵獲取結果
	 * 
	 * @param id
	 * @return
	 */
	Dict selectByPrimaryKey(Long id);

	/**
	 * 插入
	 * 
	 * @param dict
	 * @return
	 */
	int insert(Dict dict);

	/**
	 * 根據主鍵ID更新
	 * 
	 * @param dict
	 * @return
	 */
	int updateByPrimaryKey(Dict dict);

	/**
	 * 查詢所有的記錄
	 * 
	 * @return
	 */
	List<Dict> selectAll();

}
Model類
/**
 * 數據庫表對應的實體類
 * 
 * @author yanbin
 * @version 2018/3/29 11:12
 * 
 **/
public class Dict {
	private Long id;

	private String name;

	private String dictCode;

	private String dictKey;

	private String dictValue;

	private String description;

	private Long creator;

	private Date createdTime;

	private Long modifer;

	private Date modifiedTime;

	getter();
	setter();
}
業務執行操作類
/**
 * 基本的mybatis操作,基於xml配置
 *
 * @author yanbin
 * @version 2018/3/29 10:38
 *
 **/
public class BaseStart {

	/**
	 * 最基本的操作mybatis的步驟。
	 */
	public void start() throws IOException {
		// 1、獲取配置,生成Configuration 對象
		String resouce = "mybatis-config-base.xml";
		InputStream inputStream = Resources.getResourceAsStream(resouce);

		// 2、基於配置構建SqlSessionFactory對象
		SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

		// 3、獲取SqlSession對象
		SqlSession sqlSession = sessionFactory.openSession();

		try {
			// 4、通過SqlSession,獲取到對應的Mapper
			// 老的API使用方式,
			// Dict dict = (Dict)
			// sqlSession.selectOne("ybs.mybatis.mapper.DictMapper.selectByPrimaryKey", 1l);
			DictMapper dictMapper = sqlSession.getMapper(DictMapper.class);
			System.out.println(dictMapper);
			// 5、執行SQL操作
			Dict dict = dictMapper.selectByPrimaryKey(202l);
			System.out.println(dict.getId() + dict.getName());
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			// 6、關閉sqlSession
			sqlSession.close();
		}

	}

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