Mybatis映射器

select insert update delete 參數 sql元素 resultMap 緩存

映射器主要元素

  • select 查詢(可以自定義參數,返回結果集)
  • insert 插入(執行後返回一個整數,代表插入的條數)
  • update 更新 (執行後返回一個整數,代表更新的條數)
  • delete 刪除 (執行後返回一個整數,代表刪除的條數)
  • parameterMap (定義參數映射關係,即將被刪除的元素,不建議使用)
  • sql 表的列名,一次定義多個sql使用
  • resultMap 從結果集中加載對象,提供映射規則
  • cache 給定命名空間的緩存配置
  • cache-ref 其他命名空間緩存配置

select

配置


簡單例子

統計一個姓氏的用戶數量,姓氏作爲參數

  • xml:

     
           
    1
    2
    3
     
           
    <select id="countFirstName" parameterType="string" resultType="int">
    select count(*) as total form t_user where name like concat(#{firstname},'%')
    </select>
  • 接口中方法

     
           
    1
     
           
    public int countFirstName(String firstName);

自動映射

參數autoMappingBehavior當它不設置爲NONE的時候,Mybatis會提供自動映射功能,只要返回的sql列名和javaBean的屬性一直,mybatis會幫助我們回填這些字段

自動策略可以在setting元素中的配置autoMappingBehavior屬性值,包括三個值

  • NONE 取消自動映射
  • PARTIAL 只會自動映射,沒有定義嵌套結果集映射的結果集
  • FULL 會自動映射任意複雜的結果集(無論是否嵌套)

默認值爲PARTIAL

如果你的數據庫是規範命名的,即每一個單詞都用下劃線分隔,POJO採用駝峯式命名方法,那那麼你也可以設置mapUnderscoreToCamelCase爲true,這樣就可以試實現從數據庫到POJO的自動映射了

傳遞多個參數

使用Map傳遞

接口中的參數定義爲:Map params
xml中使用 resultMap=’roleMap’
sql中可以直接應用map的key值比如#{roleName}

弊端:map的業務關聯性不強,可讀性下降

使用註解傳遞

可以使用mybatis的參數註解 @Param(org.apache.ibatis.annotations.Param)來實現

接口參數之前加上註解:@Param(「roleName」) String rolename
sql中可以直接引用參數值比如 #{roleName}

弊端:如果參數多的話,這種方式會比較複雜

使用JavaBean傳遞

mybatis允許通過javabean,簡單的setter和getter方法直射參數

xml中設置
parameterType=」com.xxx.Role」

這樣就可以直接使用對象的參數了,例如#{roleName}

總結

map導致業務可讀性喪失,不要使用
@Param適合參數小於等於5個時
javaBean方式適合參數大於5時

resultMap

使用resultMap映射結果集

說明:

  • id是唯一標識,type去定義它對應是哪個javabean(也可以使用別名)
  • id屬性標註哪個屬性作爲其主鍵
  • 這樣的語句不需要使用自動映射規則,直接使用resultMap屬性指定roleResultMap即可,這樣mybatis就會使用我們的自定義規則映射

insert

mybaits會在執行插入之後返回一個整數,以表示你進行操作後插入的記錄數

配置

主鍵回填和自定義

現實中有許多我們需要處理的問題,例如主鍵自增字段,mysql裏面的主鍵需要根據一些特殊的規則去生成,在插入後我們往往需要獲得這個主鍵,以便於未來的操作,mybatis提供了實現的方法

首先我們可以說使用keyProperty屬性指定哪個是主鍵字段,同時使用useGeneratedKeys屬性告訴Mybatis這個主鍵 是否使用數據庫內置策略生成

xml配置:

這樣我們傳入的role對象無需設置id的值,mybatis會用數據庫的設置進行處理,這樣做的好處是在mybatis插入的時候,他會回填javabean的id值

如果我們需要一些特殊的關係設置id值,加入我們取消role表id自增規則,如果表t_role沒用記錄,則我們需要設置id=1,否則我們就取最大id加2,來設置主鍵

應對方法:

update與delete

update與delete元素比較簡單我們看一下配置方法

參數

注意:定義參數屬性的時候,mybatis不允許換行

參數配置

有時候我們需要處理一些特殊情況,我們可以指定類型,以確定使用哪個typehandler處理他們

 
     
1
2
3
4
5
6
 
     
#{age,javaType=int.jdbcType=NUMERIC}
#{age,javaType=int.jdbcType=NUMERIC,typeHandler=MyTypeHandler}
設置保存的精度:
#{price,javaType=double,jdbcType=NUMERIC,numericScale=2}

存儲過程支持

對於存儲過程而言,存在三種參數,輸入參數IN,輸出參數OUT,輸入輸出參數(INOUT),我們通過指定mode屬性來確定其實哪一種參數,mybtis會將存儲過程的返回結果這隻到你制定的參數中,當你返回一個遊標的時候,你還需要去設置resultMap以便mybatis將存儲過程的參數映射到對應的類型

 
     
1
 
     
#{role,mode,jdbcType=CURSOR,javaType=ResultSet,resultMap=roleResultMap}

mybatis還支持結構體,但是當你註冊參數的時候,你就需要去制定語句類型的名稱

 
     
1
 
     
#{role,mode=OUT,jdbcType=STRUCT,jdbcTypeName=MY_TYPE,resultMap=roleResultMap}

特殊字符串替換和處理(#和$)

有時候我們需要傳遞的是sql語句本身。而不是sql所需要的參數,例如一些動態表格,需要根據不同條件產生不同動態列

例如傳遞變量colums=」col1,clo2,col3…」給SQL,讓其組裝成爲SQL語句,可以寫成如下語句

 
     
1
 
     
select ${columns} from t_tablename

sql元素

可以定於可以複用的sql語句片段
例如:

 
     
1
2
3
 
     
<sql id="role_columns"
id,role_name,not
</sql>

可以在sql是使用它

resultMap

元素構成

constructor元素

加入一個pojo不存在沒有參數的構造方法
它的構造方法聲明爲

 
     
1
 
     
public RoleBean(Integer id,String roleName)

那麼我們就需要配置這個結果集

使用map存儲結果集

可以設置 resultType=」map」 可讀性下降,不推薦使用

使用POJO儲存結果集

最常用的的方式

級聯

對應sql中的join操作

級聯有三種:

  • association 代表一對一關係 比如國民和省份證
  • collection 代表一對多關係,比如班級和學生
  • discrminator 是鑑別器,它可以根據實際選擇採用哪個類所爲實例

篇幅原因不詳細說,建議少用級聯,用處不大,而且會造成複雜度增加

緩存

系統緩存

mybaits對緩存提供支持,在默認情況下,它只開啓一級緩存(一級緩存相對於同一個sqlSession而言)

所以在參數和sql完全一樣的情況下,我們使用同一個sqlSession對象調用一個Mapper方法,往往只執行一次SQL

使用sqlSession第一次查詢後,mybatis會將其放入緩存中,以後再查詢的時候,如果沒有聲明需要刷新,而且緩存沒有超時的情況下,sqlSession都只會取出當前緩存的數據,不會再次發送sql到數據庫

一級緩存在sqlSession之間是互相隔離的,爲了克服這個問題,我們需要配置二級緩存,在sqlSessionFactory層面提供給各個sqlSession對象共享

耳機緩存默認不開啓,需要進行配置,mybatis要求返回的POJO必須是可序列化的,也就是要求實現Serializable接口

配置方法:
在xml文件中配置下面內容即可

 
     
1
 
     
<cache/>

很多設置是默認設置,我們只需要這樣配置這個配置意味着:

我們也可以添加一些精細的配置:

 
     
1
 
     
<cache eviction='LRU' flushInterval="100000" size="1024" readOnly=true"/>

  • evicition:緩存回收策略

  • flushInterval 刷新間隔時間,單位是毫秒,如果你不配置它,那麼當sql被執行的時候纔會去刷新緩存

  • size 引用數目,一個正整數,代碼緩存最多可以儲存多少個對象,不宜設置過大,會導致內存溢出
  • readOnly 只讀,意味着緩存數據只能讀取不能修改,默認是false,不允許修改

自定義緩存

使用第三方緩存服務器,比如redis,我們需要mybaits爲我們提供接口
org.apache.ibatis.cache.Cache

緩存接口簡介

上面的接口需要我們去實現,假設我們已經有一個實現類com.learn.chapter4.MyCache
那麼我們需要配置如下代碼

 
     
1
 
     
<cache type="com.learn.chapter4.MyCache"/>

我們也可以配置sql層面上的緩存規則,來決定他們是否需要使用或者刷新緩存

我們根據兩個屬性:useCache和flushCache

useCache表示是否需要使用緩存
flushCache表示插入後是否需要刷新緩存

(注:內容整理自《深入淺出MyBatis技術原理與實戰》)