一、Mapper映射文件(XML)
1. mapper標簽:最頂層的配置元素;
A. namespace屬性:指向Dao接口的全限定類名;
2. resultMap標簽:建立數據庫表的列名與po類字段之間的映射關系,主要用於高級復雜的映射,如數據庫表列名與類名對應不上;
A. id元素:用於標識java對象的唯一性,不一定是數據庫的主鍵;
B. result元素:對應普通屬性;
C. collection元素:聚集元素用於處理“一對多”的關系;
D. association元素:聯合元素用於處理“一對一”的關系;
3. select標簽:SELECT查詢語句;
A. id屬性(必須配置):命名空間中唯一標識符,與Dao層接口方法名對應上;
A. parameterType屬性:要傳入語句的參數的全限定類名或別名,如果不配置,mybatis會通過ParameterHandler根據參數類型默認選擇合適的typeHandler進行處理,它可以是int, short, long, string等類型,也可以是復雜類型(如對象);
B. resultType屬性(與resultMap二選一配置):用以指定返回類型,它可以是基本類型或對象或集合,若指定該屬性就不可以用resultMap屬性;
C. resultMap屬性(與resultType二選一配置):用於引用我們通過resultMap元素標簽定義的映射類型;
D. fetchSize屬性:限制批量查詢返回結果行數。
4. insert標簽:INSERT新增語句;
A. useGeneratedKeys屬性:是否開啟主鍵回寫;
B. keyProperty屬性:主鍵對應的屬性名(實體中的屬性名);
C. statementType屬性:STATEMENT、PREPARED、CALLABLE,默認值是PREPARED;
5. update標簽:UPDATE更新語句;
6. delete標簽:DELETE刪除語句;
7. sql標簽:SQL片段,就是數據庫字段;
8. include標簽:引入SQL片段;
9. selectKey標簽:為不支持自增的主鍵生成策略。
可參考:Mybatis XML 映射器
二、主鍵回顯
1. 獲取插入數據主鍵
A. 用法:
<insert keyProperty="主鍵字段" useGeneratedKeys="true"></insert>
其中:keyColumn:主鍵列名(數據庫表中的列名);
keyProperty:主鍵對應的屬性名(實體中的屬性名);
useGeneratedKeys:是否開啟主鍵回寫, 設置為true,mybatis會使用jdbc的getGeneratedKeys()方法來獲取數據庫內部生成得到主鍵。
B. 實例:
Message message = Message.builder() .userId(userId) .messageName(messageType.getName()) .messageContent(messageContent) .build(); // 保存消息 messageMapper.saveMessage(message);
// 獲取ID long messageId = message.getId(); <insert id="saveMessage" keyProperty="id" useGeneratedKeys="true"> insert into system_message (user_id, message_name, message_content, message_status, create_time) value (#{userId}, #{messageName}, #{messageContent}, 1, now()) </insert>
C. 錯誤示例:
現象:主鍵回顯總是1;
long messageId = messageMapper.saveMessage(message);
原因:1是代表返回插入成功的行數;
解決方式:獲取ID正確方式是entity.getId(),如上圖實例代碼;
2. 自定義主鍵規則
三、聯合查詢和嵌套(遞歸)查詢
簡介:查詢樹形結構數據常用聯合查詢(嵌套結果集)和嵌套(遞歸)查詢,如菜單、部門等;
1. 聯合查詢
A. 定義:使用外連接查詢;
B. 特點:內存占用較大,但對數據庫訪問次數較少而導致消耗時間少;
2. 嵌套查詢
A. 定義:是將原來多表查詢中的聯合查詢語句拆成單個表的查詢,再使用MyBatis的語法嵌套在一起嵌套查詢使用時,先查詢A表的信息,然后依賴A和B表的外鍵約束,再次查詢B表對應到A表上的信息;
B. 特點:內存使用較小,但需要多次訪問數據庫而導致消耗時間多,產生“N + 1”問題;
C. 延遲加載:設置association或collection中屬性fetchType="lazy";
3. 遞歸查詢實例
A. VO類
package com.ruhuanxingyun.entity; import lombok.Data; import java.util.List; /** * @description: 分組分支樹 * @author: ruphie * @date: Create in 2020/1/17 15:22 * @company: ruhuanxingyun */ @Data public class GroupHostVo { /** * ID */ private Long id; /** * 父ID */ private Long parentid; /** * 名稱 */ private String name; /** * 子集 */ private List<GroupHostVo> children = new ArrayList(); }
B. mapper.xml文件
<!-- 級聯查詢返回模型 --> <resultMap id="groupHostMap" type="com.ruhuanxingyun.GroupHostVo"> <id column="id" jdbcType="BIGINT" property="id"/> <result column="parentId" jdbcType="BIGINT" property="parentid"/> <result column="name" jdbcType="VARCHAR" property="name"/> <collection column="id" property="children" ofType="com.ruhuanxingyun.GroupHostVo" select="findHostListById"/> </resultMap> <!-- 級聯查詢分組數據 --> <select id="findGroupHostTree" resultMap="groupHostMap"> select 0 as parentId, id, `name` from group where flag = 0 order by id asc </select> <!-- 級聯查詢分支數據 --> <select id="findHostListById" parameterType="long" resultType="com.ruhuanxingyun.GroupHostVo"> select sensor_id as parentId, id, `name` from host where `type` = 2 and sensor_id = #{id} order by id asc </select>
C. swagger數據展示
D. 注意事項:查詢子集數據時,select標簽里是resultType,而不是resultMap,否則會無窮遞歸,如父子ID相同,就會報內存溢出異常。