mybatis resultmap高階對映
應用場景:如果sql查詢的列名和pojo的屬性名不一致,可以使用resultMap將列名和pojo的屬性名作一個對應關係,就可以對映成功了.(如果返回值為interger等資料型別時使用resultType)
一對一
resultmap用<association>
應用場景:如order中有欄位orderdetail,是一對一關係,對映到association中的column即orderdetail中有的欄位
一對多
resultmap 用<collection>
場景:如pojo類user中有一個book屬性,則user與book屬於一對多關係(程式設計tips:userBook類可繼承user類,減少程式碼量)
tips:此處userbookresultmap可繼承自上一個userresultmap
多對多
collection和association一起使用,使用方法與上述相似,注意先後順序
mybatis的一些高階用法:
動態sql
動態sql使用方法,先將sql寫出來,再用相應的標籤替換,注意使用<trim>標籤來剔除and,or和“,”,避免出bug
(1)<sql>片段:需要查詢的欄位比較多時,可將欄位寫在該標籤中,用id來標識,使用時只需<include>即可。如
(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(需要安裝):
- dao層與mapper.xml檔案關聯,快速跳轉到對應的程式碼行
- 編輯xml檔案時支援自動補全
- 檢查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="實體類屬性名"