Mybatis學習筆記

第一章 Mybatis介紹

  下載:https://github.com/mybatis/mybatis-3/releasesjava

  Mybatisapache下的頂級項目。mysql

  MyBatis是一個優秀的持久層框架,它對jdbc的操做數據庫的過程進行封裝,使開發者只須要關注 SQL 自己,而不須要花費精力去處理例如註冊驅動、建立connection、建立statement、手動設置參數、結果集檢索等jdbc繁雜的過程代碼。git

  Mybatis經過xml或註解的方式將要執行的各類statement(statement、preparedStatemnt、CallableStatement)配置起來,並經過java對象和statement中的sql進行映射生成最終執行的sql語句,最後由mybatis框架執行sql並將結果映射成java對象並返回。程序員

  經過mybatis提供的映射方式,自由靈活生成知足須要的sql語句。github

  向preparedStatement中輸入參數自動進行輸入映射,將查詢結果集靈活映射成java對象。spring

    

 

第二章 配置文件

SqlMapConfig.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>
    <!-- 和spring整合後 environments配置將廢除-->
    <environments default="development">
        <environment id="development">
        <!-- 使用jdbc事務管理-->
            <transactionManager type="JDBC" />
        <!-- 數據庫鏈接池-->
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver" />
                <property name="url" value="jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8" />
                <property name="username" value="root" />
                <property name="password" value="mysql" />
            </dataSource>
        </environment>
    </environments>

    <mappers>
        <mapper resource="sqlmap/User.xml"/>
</mappers>

</configuration>

 

 

2.1. Properties

將參數配置在properties中,只須要在SqlMapConfig.xml中加載properties,不須要硬編碼,好比db.propertiessql

 

<properites resource="db.properties">
    <property name="age" value="18"/>
</properties>

 

properties 元素體內的屬性優先被加載,例如:age數據庫

例:apache

 

<!-- 經過properites加載  -->
    <properties resource="db.properties" />


    <!-- 和spring整合後 environments配置將廢除-->
    <environments default="development">
        <environment id="development">
        <!-- 使用jdbc事務管理-->
            <transactionManager type="JDBC" />
        <!-- 數據庫鏈接池-->
            <dataSource type="POOLED">
                <property name="driver" value="${mysql.Driver}" />
                <property name="url" value="${mysql.url}" />
                <property name="username" value="${mysql.user}" />
                <property name="password" value="${mysql.password}" />
            </dataSource>
        </environment>
</environments>

 

 

 

 

 

2.2.Settings

mybatis全局配置參數,全局參數將會影響mybatis的運行行爲。spring-mvc

Setting(設置)

Description(描述)

Valid Values(驗證值組)

Default(默認值)

cacheEnabled

在全局範圍內啓用或禁用緩存配置任何映射器在此配置下。

true | false

TRUE

lazyLoadingEnabled

在全局範圍內啓用或禁用延遲加載。禁用時,全部協會將熱加載。

true | false

TRUE

aggressiveLazyLoading

啓用時,有延遲加載屬性的對象將被徹底加載後調用懶惰的任何屬性。不然,每個屬性是按需加載。

true | false

TRUE

multipleResultSetsEnabled

容許或不容許從一個單獨的語句(須要兼容的驅動程序)要返回多個結果集。

true | false

TRUE

useColumnLabel

使用列標籤,而不是列名。在這方面,不一樣的驅動有不一樣的行爲。參考驅動文檔或測試兩種方法來決定你的驅動程序的行爲如何。

true | false

TRUE

useGeneratedKeys

容許JDBC支持生成的密鑰。兼容的驅動程序是必需的。此設置強制生成的鍵被使用,若是設置爲true,一些驅動會不兼容性,但仍然能夠工做。

true | false

FALSE

autoMappingBehavior

指定MyBatis的應如何自動映射列到字段/屬性。NONE自動映射。 PARTIAL只會自動映射結果沒有嵌套結果映射定義裏面。 FULL會自動映射的結果映射任何複雜的(包含嵌套或其餘)。

NONE, PARTIAL, FULL

PARTIAL

defaultExecutorType

配置默認執行人。SIMPLE執行人確實沒有什麼特別的。 REUSE執行器重用準備好的語句。 BATCH執行器重用語句和批處理更新。

SIMPLE REUSE BATCH

SIMPLE

defaultStatementTimeout

設置驅動程序等待一個數據庫響應的秒數。

Any positive integer

Not Set (null)

safeRowBoundsEnabled

容許使用嵌套的語句RowBounds。

true | false

FALSE

mapUnderscoreToCamelCase

從經典的數據庫列名A_COLUMN啓用自動映射到駱駝標識的經典的Java屬性名aColumn。

true | false

FALSE

localCacheScope

MyBatis的使用本地緩存,以防止循環引用,並加快反覆嵌套查詢。默認狀況下(SESSION)會話期間執行的全部查詢緩存。若是localCacheScope=STATMENT本地會話將被用於語句的執行,只是沒有將數據共享之間的兩個不一樣的調用相同的SqlSession。

SESSION | STATEMENT

SESSION

dbcTypeForNull

指定爲空值時,沒有特定的JDBC類型的參數的JDBC類型。有些驅動須要指定列的JDBC類型,但其餘像NULL,VARCHAR或OTHER的工做與通用值。

JdbcType enumeration. Most common are: NULL, VARCHAR and OTHER

OTHER

lazyLoadTriggerMethods

指定觸發延遲加載的對象的方法。

A method name list separated by commas

equals,clone,hashCode,toString

defaultScriptingLanguage

指定所使用的語言默認爲動態SQL生成。

A type alias or fully qualified class name.

org.apache.ibatis.scripting.xmltags.XMLDynamicLanguageDriver

callSettersOnNulls

指定若是setter方法​​或地圖的put方法時,將調用檢索到的值是null。它是有用的,當你依靠Map.keySet()或null初始化。注意原語(如整型,布爾等)不會被設置爲null。

true | false

FALSE

logPrefix

指定的前綴字串,MyBatis將會增長記錄器的名稱。

Any String

Not set

logImpl

指定MyBatis的日誌實現使用。若是此設置是不存在的記錄的實施將自動查找。

SLF4J | LOG4J | LOG4J2 | JDK_LOGGING | COMMONS_LOGGING | STDOUT_LOGGING | NO_LOGGING

Not set

proxyFactory

指定代理工具,MyBatis將會使用建立懶加載能力的對象。

CGLIB | JAVASSIST

 

 

<settings>
        <!-- 打開延遲加載開關 
             全局性設置懶加載。若是設爲‘false’,則全部相關聯的都會被初始化加載。
        -->
        <setting name="lazyLoadingEnabled" value="true"/>
        <!-- 將積極加載改成消極加載(按需加載)
             當設置爲‘true’的時候,懶加載的對象可能被任何懶屬性所有加載。不然,每一個屬性都按需加載。
         -->
        <setting name="aggressiveLazyLoading" value="false"/>
        
        <!-- 開啓二級緩存 
             對在此配置文件下的全部cache 進行全局性開/關設置。
        -->
        <setting name="cacheEnabled" value="true"/>
    </settings>

2.3.typeAliases

別名 映射的類型

_byte byte

_long long

_short short

_int int

_integer int

_double double

_float 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

 

自定義別名

<typeAliases>
    <!-- 單個別名定義 -->
    <typeAlias alias="user" type="cn.kai.mybatis.po.User"/>
    <!-- 批量別名定義,掃描整個包下的類,別名爲類名(首字母大寫或小寫均可以) -->
    <package name="cn.kai.mybatis.po"/>
    <package name="其它包"/>
...
</typeAliases>

 

2.4.typeHandlers(類型處理器)

 

類型處理器用於java類型和jdbc類型映射

<select id="findUserById" parameterType="int" resultType="user">
        select * from user where id = #{id}
</select>

mybatis自帶的類型處理器基本上知足平常需求,不須要單獨定義。

如IntegerTypeHandler,BooleanTypeHandler ....

 

2.5.mappers(映射器)

 

2.5.1 使用相對於類路徑的資源

<mapper resource="sqlmap/User.xml" />

2.5.2 使用徹底限定路徑

<mapper url="file:///E:\workspace\newJavaSpace\mybatis\cofnig\sqlmap\User.xml" />

 

2.5.3 使用mapper接口類路徑

 

<mapper class="cn.kai.mybatis.mapper.UserMapper"/>
此種方法要求mapper接口名稱和mapper映射文件名稱相同,且放在同一個目錄中(xxxMapper.xml和xxxMapper.java要在同一個目錄)。

 

 

2.5.3 註冊指定包下的全部mapper接口

 

<package name="cn.kai.mybatis.mapper"/>
此種方法要求mapper接口名稱和mapper映射文件名稱相同,且放在同一個目錄中

 

第三章 Mapper.xml映射文件

 

UserMapper.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 namespace="cn.kai.mybatis.mapper.UserMapper">
<select id="findUserById" parameterType="int" resultType="cn.kai.mybatis.po.User">
        select * from user where id = #{id}
    </select>
</mapper>

 

 

3.1 parameterType(輸入類型)

 

3.1.1 傳遞簡單類型

parameterType="int"

 

3.1.2 傳遞pojo對象

 

parameterType="user"  parameterType="cn.kai.mybatis.po.User"

 

3.1.3 傳遞pojo包裝對象

 

public class ItemsQueryVo {

 

private Items items;

 

3.1.4 傳遞hashmap

parameterType="hashmap"

where id=#{id}

map.put("id", 1);

map.put("username", "管理員");

 

3.2 resultType(輸出類型)

 

只有查出來的列名和pojo中的屬性名一致,才能夠映射成功

輸出簡單類型:resultType="int"

輸出pojo對象:resultType="user"

輸出pojo列表:resultType="user"

 

輸出pojo對象和輸出pojo列表在sql中定義的resultType是同樣的。

返回單個pojo對象要保證sql查詢出來的結果集爲單條,內部使用session.selectOne方法調用,mapper接口使用pojo對象做爲方法返回值。

返回pojo列表表示查詢出來的結果集可能爲多條,內部使用session.selectList方法,mapper接口使用List<pojo>對象做爲方法返回值。

 

輸出hashmap:輸出pojo對象能夠改用hashmap輸出類型,將輸出的字段名稱做爲mapkeyvalue爲字段值。

 

3.3 resultMap

若是resultMap在其餘的mapper文件引用,前邊須要加namespace

 

<?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">

<!-- namespace命名空間,做用對sql進行分類化管理 -->
<mapper namespace="cn.kai.mybatis.mapper.OrdersMapps">
    

    <!-- 根據訂單查詢用戶信息resultmap -->
    <resultMap type="cn.kai.mybatis.po.Orders" id="OrdersUserResultMap">
        <!-- orders信息 -->
        <id column="id" property="id"/>
        <result column="user_id" property="userId"/>
        <result column="number" property="number"/>
        <result column="createtime" property="createtime"/>
        <result column="note" property="note"/>
        
        <!-- user信息 -->
        <association property="user" javaType="cn.kai.mybatis.po.User">
            <id column="user_id" property="id"/>
            <result column="username" property="username"/>
            <result column="sex" property="sex"/>
            <result column="birthday" property="birthday"/>
            <result column="address" property="address"/>
        </association>
    </resultMap>
    
    <resultMap type="cn.kai.mybatis.po.Orders" id="OrdersOrderdetailResultMap" extends="OrdersUserResultMap">
        <!-- orders信息 -->
        <!-- user信息 -->
        <!-- 訂單詳情信息 -->
        <collection property="orderdetails" ofType="cn.kai.mybatis.po.Orderdetail">
            <id column="orderdetail_id" property="id"/>
            <result column="items_id" property="itemsId"/>
            <result column="items_num" property="itemsNum"/>
            <result column="orders_id" property="ordersId"/>
        </collection>
    </resultMap>

    <!-- 根據訂單查詢用戶信息 -->
    <select id="findOrdersUserResultMap" resultMap="OrdersUserResultMap">
        SELECT 
          a.*,
          b.`username`,
          b.`sex`,
          b.`birthday`,
          b.`address` 
        FROM
          orders a,
          USER b 
        WHERE a.`user_id` = b.`id` 
    </select>
    
    <!-- 根據訂單查詢訂單詳情 -->
    <select id="findOrdersOrderdetailResultMap" resultMap="OrdersOrderdetailResultMap">
        SELECT 
          a.*,
          b.`username`,
          b.`sex`,
          b.`birthday`,
          b.`address` ,
          c.`id` orderdetail_id,
          c.`items_id`,
          c.`items_num`,
          c.`orders_id`
        FROM
          orders a,
          USER b,
          orderdetail c 
        WHERE a.`user_id` = b.`id` 
          AND c.`orders_id` = a.`id` 
    </select>
    
    <!-- 查詢用戶和購買商品信息ResultMap -->
    <resultMap type="cn.kai.mybatis.po.User" id="UserAndItemsResultMap">
        <id column="user_id" property="id"/>
        <result column="username" property="username"/>
        <result column="sex" property="sex"/>
        <result column="birthday" property="birthday"/>
        <result column="address" property="address"/>
        
        <!-- ordersList信息 -->
        <collection property="ordersList" ofType="cn.kai.mybatis.po.Orders">
            <id column="id" property="id"/>
            <result column="user_id" property="userId"/>
            <result column="number" property="number"/>
            <result column="createtime" property="createtime"/>
            <result column="note" property="note"/>
            
            <collection property="orderdetails" ofType="cn.kai.mybatis.po.Orderdetail">
                <id column="orderdetail_id" property="id"/>
                <result column="items_id" property="itemsId"/>
                <result column="items_num" property="itemsNum"/>
                <result column="orders_id" property="ordersId"/>
                
                <association property="items" javaType="cn.kai.mybatis.po.Items">
                   <id column="items_id" property="id"/>
                   <result column="items_name" property="name"/>
                   <result column="items_price" property="price"/>
                </association>
            </collection>
        </collection>
        
    </resultMap>
    <!-- 查詢用戶和購買商品信息 -->
    <select id="findUserAndItems" resultMap="UserAndItemsResultMap">
       SELECT 
          a.*,
          b.`username`,
          b.`sex`,
          b.`birthday`,
          b.`address` ,
          c.`id` orderdetail_id,
          c.`items_id`,
          c.`items_num`,
          c.`orders_id`,
          d.`name` items_name,
          d.`price` items_price
        FROM
          orders a,
          USER b,
          orderdetail c,
          items d
        WHERE a.`user_id` = b.`id` 
          AND c.`orders_id` = a.`id` 
          AND c.`items_id` = d.`id`
    </select>
    
    <!-- 查詢訂單信息,延遲加載用戶信息ResultMap -->
    <resultMap type="cn.kai.mybatis.po.Orders" id="OrderLazyLogingUserResultMap">
         <!-- orders信息 -->
        <id column="id" property="id"/>
        <result column="user_id" property="userId"/>
        <result column="number" property="number"/>
        <result column="createtime" property="createtime"/>
        <result column="note" property="note"/>
        
        <!-- 延遲加載用戶信息 -->
        <association property="user" javaType="cn.kai.mybatis.po.User"
             select="cn.kai.mybatis.mapper.UserMapper.findUserById" column="user_id" fetchType="lazy">
        </association>
    </resultMap>
    <!-- 查詢訂單信息,延遲加載用戶信息 -->
    <select id="findOrderLazyLodingUser" resultMap="OrderLazyLogingUserResultMap">
        SELECT * FROM orders
    </select>
    
    <!-- 根據userId查詢訂單信息 -->
    <select id="findOrdersByUserId" parameterType="int" resultType="cn.kai.mybatis.po.Orders" >
        SELECT * FROM orders WHERE user_id = #{user_id}
    </select>
    
    <!-- 查詢用戶信息,延遲加載訂單信息 ResultMap -->
    <resultMap type="cn.kai.mybatis.po.User" id="UserLazyLodingOrdersResultMap">
        <id column="id" property="id"/>
        <result column="username" property="username"/>
        <result column="sex" property="sex"/>
        <result column="birthday" property="birthday"/>
        <result column="address" property="address"/> 
            <!-- 延遲加載訂單信息 -->   
            <collection property="ordersList" ofType="cn.kai.mybatis.po.Orders" select="findOrdersByUserId" column="id" fetchType="lazy">
            </collection>
    </resultMap>
    <!-- 查詢用戶信息,延遲加載訂單信息 -->
    <select id="findUserLazyLodingOrders" resultMap="UserLazyLodingOrdersResultMap">
        SELECT * FROM USER
    </select>
    
</mapper>

 

 

第四章 mapper接口

 

  1. mapper.xmlnamespace就是mapper.java的類全路徑
  2. Mapper接口方法名和Mapper.xml中定義的statementid相同
  3. Mapper接口方法的輸入參數類型和mapper.xml中定義的statementparameterType的類型相同
  4. Mapper接口方法的輸出參數類型和mapper.xml中定義的statementresultType的類型相同

 

  使用註解來映射簡單語句

  

public interface BlogMapper {
  @Select("SELECT * FROM blog WHERE id = #{id}")
  Blog selectBlog(int id);
}

 

第五章 動態sql

5.1. If

<select id="findUserList" parameterType="user" resultType="user">
        select * from user 
        where 1=1 
        <if test="id!=null and id!=''">
        and id=#{id}
        </if>
        <if test="username!=null and username!=''">
        and username like '%${username}%'
        </if>
</select>

5.2. Where

<where />能夠自動處理第一個and,不用擔憂會多一個and

<select id="findUserList" parameterType="user" resultType="user">
        select * from user 
        <where>
        <if test="id!=null and id!=''">
        and id=#{id}
        </if>
        <if test="username!=null and username!=''">
        and username like '%${username}%'
        </if>
        </where>
    </select>

5.3 foreach

5.4 Sql片斷

 

Sql中可將重複的sql提取出來,使用時用include引用便可,最終達到sql重用的目的

 

<sql id="query_user_where">
    <if test="id!=null and id!=''">
        and id=#{id}
    </if>
    <if test="username!=null and username!=''">
        and username like '%${username}%'
    </if>
</sql>
<select id="findUserList" parameterType="user" resultType="user">
        select * from user 
        <where>
        <include refid="query_user_where"/>
        </where>
    </select>

 

若是引用其它mapper.xmlsql片斷,則在引用時須要加上namespace,以下:

<include refid="namespace.sql片斷」/>

 

 

第六章 mybatis框架

 

 

6.1. SqlMapConfig.xml文件名字不固定

 

全局配置文件,配置了數據源,事務等

 

6.2. 配置映射文件(配置sql語句)

 

mapper.xml

 

6.3. SqlSessionFactory

SqlSession線程不安全,最好放在方法體內建立

 

建立SqlSession:操做數據庫(發出sql增、刪、改、查)

//mybatis配置文件
            String resource = "SqlMapConfig.xml";
            
            InputStream inputStream;
            inputStream = Resources.getResourceAsStream(resource);
            //建立會話工廠
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
            
            //經過工廠獲得SqlSession
            sqlSession = sqlSessionFactory.openSession();

 

6.4. Exection(執行器)

 

是一個接口(基本執行器,緩存執行器)

 

SqlSession內部經過執行器操做數據庫

 

6.5. Mapped statement(底層封裝對象)

 

對操做數據庫存儲封裝、包括sql語句,輸入參數、輸出結果類型

 

輸入參數類型:java簡單類型、hashmappojo自定義類型

 

#{}   ${}:

 

使用佔位符#{}能夠有效防止sql注入

 

#{}能夠接收簡單類型值或pojo屬性值,若是parameterType傳輸單個簡單類型值,#{}括號中能夠是value或其它名稱。

 

${}和#{}不一樣,經過${}能夠將parameterType 傳入的內容拼接在sql中且不進行jdbc類型轉換, ${}能夠接收簡單類型值或pojo屬性值,若是parameterType傳輸單個簡單類型值,${}括號中只能是value。

 

使用${}不能防止sql注入

 

第七章 延遲加載

當須要查詢關聯信息時再去數據庫查詢,默認不去關聯查詢,提升數據庫性能。

只有使用resultMap支持延遲加載設置。

 

7.1. 打開延遲開關

 

方法1、

 

<!-- setting:mybatis全局配置參數,全局參數將會影響mybatis的運行行爲。 -->

 

    <settings>

 

        <!-- 打開延遲加載開關

 

            全局性設置懶加載。若是設爲false’,則全部相關聯的都會被初始化加載。

 

        -->

 

        <setting name="lazyLoadingEnabled" value="true"/>

 

        <!-- 將積極加載改成消極加載(按需加載)

 

            當設置爲true’的時候,懶加載的對象可能被任何懶屬性所有加載。不然,每一個屬性都按需加載。

 

         -->

 

        <setting name="aggressiveLazyLoading" value="false"/>

 

</settings>

 

 

 

方法2、用fetchType="lazy" 設置單個延遲加載

 

<!-- 延遲加載用戶信息 -->

 

        <association property="user" javaType="cn.kai.mybatis.po.User"

 

             select="cn.kai.mybatis.mapper.UserMapper.findUserById" column="user_id" fetchType="lazy">

 

        </association>

 

7.2. 實例

<!-- 查詢訂單信息,延遲加載用戶信息 -->
    <select id="findOrderLazyLodingUser" resultMap="OrderLazyLogingUserResultMap">
        SELECT * FROM orders
</select>

<!-- 查詢訂單信息,延遲加載用戶信息ResultMap -->
    <resultMap type="cn.kai.mybatis.po.Orders" id="OrderLazyLogingUserResultMap">
         <!-- orders信息 -->
        <id column="id" property="id"/>
        <result column="user_id" property="userId"/>
        <result column="number" property="number"/>
        <result column="createtime" property="createtime"/>
        <result column="note" property="note"/>
        
        <!-- 延遲加載用戶信息 -->
        <association property="user" javaType="cn.kai.mybatis.po.User"
             select="cn.kai.mybatis.mapper.UserMapper.findUserById" column="user_id" fetchType="lazy">
        </association>
    </resultMap>

List<Orders> list = ordersMapps.findOrderLazyLodingUser();            
            for(Orders order: list) {
                //調用getUser時延遲加載查詢數據庫
                User user = order.getUser();
                System.out.println(user);
            }

 

 

第八章 查詢緩存

8.1. 一級緩存

一級緩存是SqlSession級別的緩存。在操做數據庫時須要構造 sqlSession對象,在對象中有一個數據結構(HashMap)用於存儲緩存數據。不一樣的sqlSession之間的緩存數據區域(HashMap)是互相不影響的。

若是sqlSession去執行commit操做(執行插入、更新、刪除),清空SqlSession中的一級緩存,這樣作的目的爲了讓緩存中存儲的是最新的信息,避免髒讀。

若是緩存中有數據就不用從數據庫中獲取,大大提升系統性能。

 

 

 

 

 

8.2. 二級緩存

 

二級緩存區域是根據mappernamespace劃分的,相同namespacemapper查詢數據放在同一個區域,若是使用mapper代理方法每一個mappernamespace都不一樣,此時能夠理解爲二級緩存區域是根據mapper劃分。

 

每次查詢會先從緩存區域找,若是找不到從數據庫查詢,查詢到數據將數據寫入緩存。

 

Mybatis內部存儲緩存使用一個HashMapkeyhashCode+sqlId+Sql語句。value爲從查詢出來映射生成的java對象

 

sqlSession執行insertupdatedelete等操做commit提交後會清空緩存區域。

 

 

 

 

 

開啓二級緩存:

 

1.在覈心配置文件SqlMapConfig.xml中加入

 

<setting name="cacheEnabled" value="true"/>

 

2.要在你的Mapper映射文件中添加一行:  <cache /> ,表示此mapper開啓二級緩存。

 

 

 

二級緩存須要查詢結果映射的pojo對象實現java.io.Serializable接口實現序列化和反序列化操做,注意若是存在父類、成員pojo都須要實現序列化接口。

 

public class Orders implements Serializable

 

public class User implements Serializable

 

 

 

禁用二級緩存:

 

<select ... useCache="false">

 

每次查詢都會發出sql去查詢

 

 

 

刷新緩存

 

mapper的同一個namespace中,若是有其它insertupdatedelete操做數據後須要刷新緩存,若是不執行刷新緩存會出現髒讀。

 

 

 

 設置statement配置中的flushCache="true" 屬性,默認狀況下爲true即刷新緩存,若是改爲false則不會刷新。使用緩存時若是手動修改數據庫表中的查詢數據會出現髒讀。

 

以下:

 

<insert id="insertUser" parameterType="cn.itcast.mybatis.po.User" flushCache="true">

 

 

 

flushInterval(刷新間隔)

 

<cache  eviction="FIFO"  flushInterval="60000"  size="512"  readOnly="true"/>

 

這個更高級的配置建立了一個 FIFO 緩存,並每隔 60 秒刷新,存數結果對象或列表的 512 個引用,並且返回的對象被認爲是隻讀的,所以在不一樣線程中的調用者之間修改它們會致使衝突。可用的收回策略有默認的是 LRU:

 

1.LRU – 最近最少使用的:移除最長時間不被使用的對象。

 

2.FIFO – 先進先出:按對象進入緩存的順序來移除它們。

 

3.SOFT – 軟引用:移除基於垃圾回收器狀態和軟引用規則的對象。

 

4.WEAK – 弱引用:更積極地移除基於垃圾收集器狀態和弱引用規則的對象。

 

 

 

 

 

 

 

8.3. mybatis整合ehcache

 

爲了提升系統併發,性能、通常對系統進行分佈式部署,不使用分佈緩存,緩存的數據在各各服務單獨存儲,不方便系統開發。因此要使用分佈式緩存對緩存數據進行集中管理。

 

mybatis沒法實現分佈式緩存,須要和其它分佈式緩存框架進行整合。

 

 

 

mybatis提供了一個cache接口,若是要實現本身的緩存邏輯,實現cache接口開發便可。

 

mybatisehcache整合,mybatisehcache整合包中提供了一個cache接口的實現類。

 

mybatis默認實現cachePerpetualCache

 

 

 

整合方法

  1. 加入ehcache包 

    

  2. 緩存配置文件ehcache.xml

 

 

    

<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:noNamespaceSchemaLocation="../config/ehcache.xsd">
    <diskStore path="F:\develop\ehcache" />
    <defaultCache 
        maxElementsInMemory="1000" 
        maxElementsOnDisk="10000000"
        eternal="false" 
        overflowToDisk="false" 
        timeToIdleSeconds="120"
        timeToLiveSeconds="120" 
        diskExpiryThreadIntervalSeconds="120"
        memoryStoreEvictionPolicy="LRU">
    </defaultCache>
</ehcache>

屬性說明:

 diskStore:指定數據在磁盤中的存儲位置。

defaultCache:當藉助CacheManager.add("demoCache")建立Cache時,EhCache便會採用<defalutCache/>指定的的管理策略

如下屬性是必須的:

maxElementsInMemory - 在內存中緩存的element的最大數目

maxElementsOnDisk - 在磁盤上緩存的element的最大數目,如果0表示無窮大

eternal - 設定緩存的elements是否永遠不過時。若是爲true,則緩存的數據始終有效,若是爲false那麼還要根據timeToIdleSecondstimeToLiveSeconds判斷

overflowToDisk - 設定當內存緩存溢出的時候是否將過時的element緩存到磁盤上

如下屬性是可選的:

timeToIdleSeconds - 當緩存在EhCache中的數據先後兩次訪問的時間超過timeToIdleSeconds的屬性取值時,這些數據便會刪除,默認值是0,也就是可閒置時間無窮大

timeToLiveSeconds - 緩存element的有效生命期,默認是0.,也就是element存活時間無窮大

diskSpoolBufferSizeMB 這個參數設置DiskStore(磁盤緩存)的緩存區大小.默認是30MB.每一個Cache都應該有本身的一個緩衝區.

diskPersistent - VM重啓的時候是否啓用磁盤保存EhCache中的數據,默認是false

diskExpiryThreadIntervalSeconds - 磁盤緩存的清理線程運行間隔,默認是120秒。每一個120s,相應的線程會進行一次EhCache中數據的清理工做

memoryStoreEvictionPolicy - 當內存緩存達到最大,有新的element加入的時候, 移除緩存中element的策略。默認是LRU(最近最少使用),可選的有LFU(最不常使用)和FIFO(先進先出)

 

  3. 開啓ehcache緩存

    <cache type="org.mybatis.caches.ehcache.EhcacheCache"/>

    根據需求調整緩存參數:

    

<cache type="org.mybatis.caches.ehcache.EhcacheCache" > 
        <property name="timeToIdleSeconds" value="3600"/>
        <property name="timeToLiveSeconds" value="3600"/>
        <!-- 同ehcache參數maxElementsInMemory -->
        <property name="maxEntriesLocalHeap" value="1000"/>
        <!-- 同ehcache參數maxElementsOnDisk -->
        <property name="maxEntriesLocalDisk" value="10000000"/>
        <property name="memoryStoreEvictionPolicy" value="LRU"/>
    </cache>

 

第九章 mybatis spring整合

 

須要spring經過單例方式管理SqlSessionFactory

 

springmybatis整合生成代理對象,使用SqlSessionFactory建立SqlSession。(springmybatis整合自動完成)

 

持久層的mapper都須要由spring進行管理。

 

 

 

Jar包:

 

mybatis3.2.7jar

 

spring3.2.0jar

 

9.1. Spring配置文件applicationContext.xml

 

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
        http://www.springframework.org/schema/beans/spring-beans-3.2.xsd 
        http://www.springframework.org/schema/mvc 
        http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd 
        http://www.springframework.org/schema/context 
        http://www.springframework.org/schema/context/spring-context-3.2.xsd 
        http://www.springframework.org/schema/aop 
        http://www.springframework.org/schema/aop/spring-aop-3.2.xsd 
        http://www.springframework.org/schema/tx 
        http://www.springframework.org/schema/tx/spring-tx-3.2.xsd ">
        <!-- 加載配置文件 -->
        <context:property-placeholder location="classpath:db.properties"/>
        <!-- dbcp數據源 -->
        <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
            <property name="driverClassName" value="${mysql.Driver}"/>
            <property name="url" value="${mysql.url}" />
            <property name="username" value="${mysql.user}"/>
            <property name="password" value="${mysql.password}"/>
        </bean>
        
        <!-- oracle數據源 -->
        <!-- <bean id="dataSource" class="oracle.jdbc.pool.OracleDataSource" destroy-method="close">
            <property name="serviceName" value="${mysql.Driver}"/>
            <property name="url" value="${mysql.url}" />
            <property name="user" value="${mysql.user}"/>
            <property name="password" value="${mysql.password}"/>
        </bean> -->
        
        <!-- sqlSessionFactory -->
        <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
            <!-- 配置數據源 -->
            <property name="dataSource" ref="dataSource"/>
            <!-- 配置mybatis配置文件 -->
            <property name="configLocation" value="./mybatis/SqlMapConfig.xml"/>
        </bean>
        
        <bean id="userDao" class="cn.kai.sm.dao.impl.UserDaoImpl">
            <property name="sqlSessionFactory" ref="sqlSessionFactory"/>
        </bean>
        
        <bean id="userMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">
            <!-- 設置mapper接口 -->
            <property name="mapperInterface" value="cn.kai.sm.mapper.UserMapper"/>
            <property name="sqlSessionFactory" ref="sqlSessionFactory"/>
        </bean>
        
</beans>

 

9.2. daodao的實現

 

1)dao的實現須要繼承SqlSessionDaoSupport

 

public class UserDaoImpl extends SqlSessionDaoSupport implements UserDao {

    @Override
    public User findUserById(int id) throws Exception {
        
        SqlSession sqlSession = getSqlSession();
        
        return sqlSession.selectOne("userMapper.findUserById", id);
        
    }

}

 

2)加載bean

 

<!-- dao的實現的方法加載userbean -->
        <bean id="userDao" class="cn.kai.sm.dao.impl.UserDaoImpl">
            <property name="sqlSessionFactory" ref="sqlSessionFactory"/>
        </bean>

 

3)測試

 

private ApplicationContext applicationContext;
    
    @Before
    public void setUp() throws Exception{
        applicationContext = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
    }
    
    @Test
    public void testFindUserById() throws Exception {
        UserDao userdao = (UserDao) applicationContext.getBean("userDao");
        
        User user = userdao.findUserById(29);
        
        System.out.println(user);
    }

 

9.3. 使用mapper實現

1<!-- 經過mapper的方法加載userbean -->

 

<bean id="userMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">
            <!-- 設置mapper接口 -->
            <property name="mapperInterface" value="cn.kai.sm.mapper.UserMapper"/>
            <property name="sqlSessionFactory" ref="sqlSessionFactory"/>
        </bean>

 

2<!-- 批量掃描mapper加載userbean -->

 

<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
            <!-- 要掃描的包,多個包名用,隔開 -->
            <property name="basePackage" value="cn.kai.sm.mapper"/>
            <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
        </bean>

 

3)測試

 

UserMapper userMapper = (UserMapper) applicationContext.getBean("userMapper");
        
        User user = userMapper.findUserById(29);
        
        System.out.println(user);

 

 

第十章 逆向工程

mybaits須要程序員本身編寫sql語句,mybatis官方提供逆向工程 能夠針對單表自動生成mybatis執行所須要的代碼(mapper.java,mapper.xmlpo..

 

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
  PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
  "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">

<generatorConfiguration>
    <context id="testTables" targetRuntime="MyBatis3">
        <commentGenerator>
            <!-- 是否去除自動生成的註釋 true:是 : false:否 -->
            <property name="suppressAllComments" value="true" />
        </commentGenerator>
        <!--數據庫鏈接的信息:驅動類、鏈接地址、用戶名、密碼 -->
        <jdbcConnection driverClass="com.mysql.jdbc.Driver"
            connectionURL="jdbc:mysql://localhost:3306/mybatis" userId="root"
            password="chenkai123">
        </jdbcConnection>
        <!-- <jdbcConnection driverClass="oracle.jdbc.OracleDriver"
            connectionURL="jdbc:oracle:thin:@127.0.0.1:1521:yycg" 
            userId="yycg"
            password="yycg">
        </jdbcConnection> -->

        <!-- 默認false,把JDBC DECIMAL 和 NUMERIC 類型解析爲 Integer,爲 true時把JDBC DECIMAL 和 
            NUMERIC 類型解析爲java.math.BigDecimal -->
        <javaTypeResolver>
            <property name="forceBigDecimals" value="false" />
        </javaTypeResolver>

        <!-- targetProject:生成PO類的位置 -->
        <javaModelGenerator targetPackage="cn.kai.sm.bean"
            targetProject=".\src">
            <!-- enableSubPackages:是否讓schema做爲包的後綴 -->
            <property name="enableSubPackages" value="false" />
            <!-- 從數據庫返回的值被清理先後的空格 -->
            <property name="trimStrings" value="true" />
        </javaModelGenerator>
        <!-- targetProject:mapper映射文件生成的位置 -->
        <sqlMapGenerator targetPackage="cn.kai.sm.mapper" 
            targetProject=".\src">
            <!-- enableSubPackages:是否讓schema做爲包的後綴 -->
            <property name="enableSubPackages" value="false" />
        </sqlMapGenerator>
        <!-- targetPackage:mapper接口生成的位置 -->
        <javaClientGenerator type="XMLMAPPER"
            targetPackage="cn.kai.sm.mapper" 
            targetProject=".\src">
            <!-- enableSubPackages:是否讓schema做爲包的後綴 -->
            <property name="enableSubPackages" value="false" />
        </javaClientGenerator>
        <!-- 指定數據庫表 -->
        <table tableName="items"></table>
        <table tableName="orders"></table>
        <table tableName="orderdetail"></table>
        <table tableName="user"></table>

        
    </context>
</generatorConfiguration>

 

 

public class GeneratorSqlmap {

    public void generator() throws Exception{

        List<String> warnings = new ArrayList<String>();
        boolean overwrite = true;
        //指定 逆向工程配置文件
        File configFile = new File("generatorConfig.xml"); 
        ConfigurationParser cp = new ConfigurationParser(warnings);
        Configuration config = cp.parseConfiguration(configFile);
        DefaultShellCallback callback = new DefaultShellCallback(overwrite);
        MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config,
                callback, warnings);
        myBatisGenerator.generate(null);

    } 
    public static void main(String[] args) throws Exception {
        try {
            GeneratorSqlmap generatorSqlmap = new GeneratorSqlmap();
            generatorSqlmap.generator();
        } catch (Exception e) {
            e.printStackTrace();
        }
        
    }

}
相關文章
相關標籤/搜索