select insert update delete 參數 sql元素 resultMap 緩存
統計一個姓氏的用戶數量,姓氏作爲參數
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屬性值,包括三個值
默認值爲PARTIAL
如果你的數據庫是規範命名的,即每一個單詞都用下劃線分隔,POJO採用駝峯式命名方法,那那麼你也可以設置mapUnderscoreToCamelCase爲true,這樣就可以試實現從數據庫到POJO的自動映射了
接口中的參數定義爲:Map params
xml中使用 resultMap=’roleMap’
sql中可以直接應用map的key值比如#{roleName}
弊端:map的業務關聯性不強,可讀性下降
可以使用mybatis的參數註解 @Param(org.apache.ibatis.annotations.Param)來實現
接口參數之前加上註解:@Param(「roleName」) String rolename
sql中可以直接引用參數值比如 #{roleName}
弊端:如果參數多的話,這種方式會比較複雜
mybatis允許通過javabean,簡單的setter和getter方法直射參數
xml中設置
parameterType=」com.xxx.Role」
這樣就可以直接使用對象的參數了,例如#{roleName}
map導致業務可讀性喪失,不要使用
@Param適合參數小於等於5個時
javaBean方式適合參數大於5時
說明:
mybaits會在執行插入之後返回一個整數,以表示你進行操作後插入的記錄數
現實中有許多我們需要處理的問題,例如主鍵自增字段,mysql裏面的主鍵需要根據一些特殊的規則去生成,在插入後我們往往需要獲得這個主鍵,以便於未來的操作,mybatis提供了實現的方法
首先我們可以說使用keyProperty屬性指定哪個是主鍵字段,同時使用useGeneratedKeys屬性告訴Mybatis這個主鍵 是否使用數據庫內置策略生成
這樣我們傳入的role對象無需設置id的值,mybatis會用數據庫的設置進行處理,這樣做的好處是在mybatis插入的時候,他會回填javabean的id值
如果我們需要一些特殊的關係設置id值,加入我們取消role表id自增規則,如果表t_role沒用記錄,則我們需要設置id=1,否則我們就取最大id加2,來設置主鍵
注意:定義參數屬性的時候,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語句片段
例如:
1
2
3
|
<sql id="role_columns"
id,role_name,not
</sql>
|
加入一個pojo不存在沒有參數的構造方法
它的構造方法聲明爲
1
|
public RoleBean(Integer id,String roleName)
|
可以設置 resultType=」map」 可讀性下降,不推薦使用
對應sql中的join操作
級聯有三種:
篇幅原因不詳細說,建議少用級聯,用處不大,而且會造成複雜度增加
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"/>
|
flushInterval 刷新間隔時間,單位是毫秒,如果你不配置它,那麼當sql被執行的時候纔會去刷新緩存
使用第三方緩存服務器,比如redis,我們需要mybaits爲我們提供接口
org.apache.ibatis.cache.Cache
上面的接口需要我們去實現,假設我們已經有一個實現類com.learn.chapter4.MyCache
那麼我們需要配置如下代碼
1
|
<cache type="com.learn.chapter4.MyCache"/>
|
我們也可以配置sql層面上的緩存規則,來決定他們是否需要使用或者刷新緩存
我們根據兩個屬性:useCache和flushCache
useCache表示是否需要使用緩存
flushCache表示插入後是否需要刷新緩存
(注:內容整理自《深入淺出MyBatis技術原理與實戰》)