mybatis學習與踩坑記錄

zhusir發表於2018-08-22

mybatis resultmap高階對映

應用場景:如果sql查詢的列名和pojo的屬性名不一致,可以使用resultMap將列名和pojo的屬性名作一個對應關係,就可以對映成功了.(如果返回值為interger等資料型別時使用resultType)

一對一

 resultmap用<association>

應用場景:如order中有欄位orderdetail,是一對一關係,對映到association中的column即orderdetail中有的欄位

mybatis學習與踩坑記錄

一對多

resultmap 用<collection>

場景:如pojo類user中有一個book屬性,則user與book屬於一對多關係(程式設計tips:userBook類可繼承user類,減少程式碼量)


mybatis學習與踩坑記錄


tips:此處userbookresultmap可繼承自上一個userresultmap

多對多

collection和association一起使用,使用方法與上述相似,注意先後順序

mybatis的一些高階用法:

動態sql

動態sql使用方法,先將sql寫出來,再用相應的標籤替換,注意使用<trim>標籤來剔除and,or和“,”,避免出bug

(1)<sql>片段:需要查詢的欄位比較多時,可將欄位寫在該標籤中,用id來標識,使用時只需<include>即可。如

mybatis學習與踩坑記錄

(2) <trim>標籤:

使用:

  • <trim>:prefix="":字首
  • prefixoverride="AND | OR":去掉第一個and或or
  • suffixoverride=",":去掉最後一個,
  • suffix=“”字尾

應用場景:在動態sql使用過程中,需要判斷欄位是否為空,這時就會出現sql語句錯誤的情況,如多了and,or或著導致某些地方語句不正確,這時會出現sql執行出錯或者查不到資料的情況,需要用該標籤進行過濾(在實際使用中要特別注意,如果忽視找bug需要好久。。。)

(3)where-if語句,set-if語句

select * from user 
        <where>
                <if    test="username != null ">
                    username = #{username}
                </if>
        </where>
複製程式碼

說明:通用<where>,該標籤會判斷返回語=語句中是否有值,有得話就會插入一個where,而且如果返回值的開頭是and 或or時他會剔除掉。同理,set-if語句與上述語句作用類似。這兩個標籤通常用<trim>替換

(4)choose(when,otherise)

說明:與java中的switch語句類似

使用:

<choose>
        <when test="username != null  and username !=' '  "> //不為空格用單引號
        </when>
        <otherwise>  ....
        </otherwise>
</choose>
複製程式碼

(5)foreach語句

<foreach  collection="ids"   item="id"   open="and ("  close=")"  separator="or" >
</foreach>
複製程式碼

說明:

  • collection:指定輸入物件中的集合屬性
  • item:每次遍歷生成的物件
  • open:開始遍歷時的拼接字串
  • close:結束時拼接的字串
  • separator:遍歷物件之間需要拼接的字串

(6)   bind語句:

使用bind元素我們可以預先定義一些變數,然後在查詢語句中使用,如

<bind name="un" value="username + '%' "></bind>

SELECT* FROM user2 WHERE user_name LIKE #{un}

繼承

resultmap使用繼承機制可以減少很多程式碼量,而且簡單直觀,相應的pojo類繼承也是同理

mybatis三劍客

(1)mybatis-generater:用於快速生成pojo,dao,mapper和mapper.xml

(2)mybatis-plugin(需要安裝):

  1. dao層與mapper.xml檔案關聯,快速跳轉到對應的程式碼行
  2. 編輯xml檔案時支援自動補全
  3. 檢查id衝突或屬性衝突

(3)mybatis-pagehalper:一個動態分頁和排序的外掛,原理是通過spring的AOP來實現的,這個外掛能在執行sql的時候,把相關的資料再執行一次

mybatis二級快取

系統已經預設開啟了一級快取,當我們獲取到一個SqlSession物件之後,如果呼叫SqlSession中的同一個方法查詢同一條資料,那麼第二次查詢將不會去資料庫中查詢。

手動開啟快取:在mapper.xml中配置<cache>節點:如

<cache eviction="LRU" size=1024 readOnly=true />

replace into語法

replace into 跟 insert 功能類似,不同點在於:replace into 首先嚐試插入資料到表中, 如果發現表中已經有此行資料(根據主鍵或者唯一索引判斷)則先刪除此行資料,然後插入新的資料。 否則,直接插入新資料。

要注意的是:插入資料的表必須有主鍵或者是唯一索引!否則的話,replace into 會直接插入資料,這將導致表中出現重複的資料。

mybatsi註解方式

例如:

一對一或一對多屬性用@many,@one

@Select("select * from group_info where id = #{groupId}")
@Results({     //宣告結果集,當返回結果不是java基本資料型別時使用
@Result(property ="id", column ="id"),              //property為實體類中的屬性,column為資料庫中的欄位
@Result(property ="authorities", column ="id",   //colunm為authorities實體類對應資料庫的欄位
javaType = List.class,
many =@Many(select ="com.baicizhan.dao.user.GroupAuthMapper.getGroupAuthorities",
fetchType = FetchType.EAGER))
})複製程式碼

@Insert("insert into user_session(xdid, openid, token, wx_session) values(#{xdid}, #{openid}, #{token}, #{wxSession})")
@SelectKey(statement="SELECT LAST_INSERT_ID()", keyProperty="id", before=false, resultType=int.class)複製程式碼

@SelectKey的作用:SelectKey在Mybatis中是為了解決Insert資料時不支援主鍵自動生成的問題,並且返回的值是自增的主鍵


mybatis註解方式高階用法

1.動態sql:

在註解上不能直接使用動態的SQL,需要在其前後加入<script></script>

2.註解方式實現like語句:LIKE 也是不能夠直接使用的 可以藉助concat函式實現

例如:@Select("SELECT name from user WHERE email LIKE concat(#{prefix},'%') limit 5")


踩坑記錄

大小寫導致欄位與資料庫對映錯誤問題

MYSQL在Windows下不區分大小寫,但在Linux上預設區分大小寫。因此,資料庫名、表名、欄位名都不允許出現任何大寫字母,避免節外生枝。以下劃線分割

@Select("select * from group_info where id = #{groupId}")
@Results({
@Result(property ="id", column ="id"),
@Result(property ="authorities", column ="id",
javaType = List.class,many =@Many(select ="com.baicizhan.dao.user.GroupAuthMapper.getGroupAuthorities",
fetchType = FetchType.EAGER))
})複製程式碼

mapper檔案對映時mybatis會選擇駝峰式的方式對資料庫的列與實體類對映,有時資料庫中的列用“_”進行命名時就會出現對映不到的情況

解決方法:

1.在sql語句中使用“AS”關鍵字使實體類與資料庫列名對映,如Open_ID as openId

2.在ResultMap中配置屬性:column = "資料庫列名",propetis="實體類屬性名"





相關文章