-
一對一映射:
-
使用自動映射處理一對一關係:
public class User { private Integer id; private String username; private String userEmail; /** * 角色 */ private Role role; // 省略其它代碼 } public class Role { private Integer id; private String roleName; // 省略其它代碼 } <select id="selectUserAndRoleById" resultType="study.User"> SELECT id, username, userEmail, <!--注意這裏的別名--> role.id AS "role.id", <!--注意這裏的別名--> role.role_name AS "role.roleName" FROM user INNER JOIN user_role ON user_role.role_id = user.id INNER JOIN role ON role.id = user_role.role_id WHERE user.id = #{id} </select>
-
使用 resultMap 配置一對一映射:
-
一般寫法:
<resultMap id="uesrRoleMap" type="study.User"> <id property="id" column="id"/> <result property="username" column="username"/> <result property="userEmail" column="user_email"/> <result property="role.id" column="role_id"/> <result property="role.roleName" column="role_name"/> </resultMap> <select id="selectUserAndRoleById" resultMap="uesrRoleMap"> SELECT id, username, userEmail, <!--注意這裏的別名--> role.id AS role_id, <!--注意這裏的別名--> role.role_name FROM user INNER JOIN user_role ON user_role.role_id = user.id INNER JOIN role ON role.id = user_role.role_id WHERE user.id = #{id} </select>
注意這裏在 resultMap 中配置的 column 名稱要和 SQL 語句查詢結果的別名相同.
-
使用繼承的方式:
<!--User 的 resultMap--> <resultMap id="userMap" type="study.User"> <!--這些是可以被繼承的--> <id property="id" column="id"/> <result property="username" column="username"/> <result property="userEmail" column="user_email"/> </resultMap> <!--帶 Role 的 User 的 resultMap--> <resultMap id="uesrRoleMap" extends="userMap" type="study.User"> <result property="role.id" column="role_id"/> <result property="role.roleName" column="role_name"/> </resultMap>
這裏繼承的只是 userMap 中的 id 和 result 子元素.
-
使用 Association 方式:
<resultMap id="uesrRoleMap" extends="userMap" type="study.User"> <association property="role" columnPrefix="role_" javaType="study.Role"> <result property="id" column="id"/> <result property="roleName" column="role_name"/> </association> </resultMap> <select id="selectUserAndRoleById" resultMap="uesrRoleMap"> SELECT id, username, userEmail, <!--注意這裏的別名, 所有列名必須要有 role_ 前綴--> role.id AS role_id, <!--注意這裏的別名, 所有列名必須要有 role_ 前綴--> role.role_name AS role_role_name FROM user INNER JOIN user_role ON user_role.role_id = user.id INNER JOIN role ON role.id = user_role.role_id WHERE user.id = #{id} </select>
-
-
association 標籤的嵌套查詢:
<resultMap id="uesrRoleMap" extends="userMap" type="study.User"> <association property="role" javaType="study.Role" column="{id=role_ID}" select="study.mapper.RoleMapper.selectRoleById"/> </resultMap> <select id="selectUserAndRoleByIdSelect" resultMap="uesrRoleMap"> SELECT id, username, userEmail, user_role.role_id <!--注意這裏並沒有從 role 表中查詢信息了--> FROM user INNER JOIN user_role ON user_role.role_id = user.id WHERE user.id = #{id} </select> <select id="selectRoleById" resultMap="roleMap"> SELECT id, role_name FROM role WHERE id = #{id} </select>
這裏還可以將 fetchType 設置爲 lazy. 這樣設置之後, 只有當調用
User#getRole()
方法纔會執行嵌套查詢去獲取數據. 這時需要將在
mybatis-config.xml 中增加:<settings> <setting name="aggressiveLazyLoading" value="false"/> </settings>
Mybatis 還提供了 lazyLoadTriggerMethods 來定義某些方法, 當調用這些方法時, 會加載全部的延遲加載數據.
-
-
一對多映射:
-
collection 集合的嵌套結果映射:
public class User { private Integer id; private String username; private String userEmail; /** * 角色 */ private List<Role> roles; // 省略其它代碼 } <resultMap id="uesrRoleMap" extends="userMap" type="study.User"> <collection property="roles" columnPrefix="role_" javaType="study.Role" <!--這裏引用 roleMap --> resultMap="study.mapper.RoleMapper.roleMap"/> </resultMap> <select id="selectAllUserAndRoles" resultMap="uesrRoleMap"> SELECT id, username, userEmail, <!--注意這裏的別名, 所有列名必須要有 role_ 前綴--> role.id AS role_id, <!--注意這裏的別名, 所有列名必須要有 role_ 前綴--> role.role_name AS role_role_name FROM user INNER JOIN user_role ON user_role.role_id = user.id INNER JOIN role ON role.id = user_role.role_id </select>
Mybatis 在處理結果的時候, 會判斷結果是否相同. 如果是相同的結果, 則只會保留第一個結果. MyBatis 判斷結果是否相同時, 最簡單的是根據 resultMap 中映射配置的 id 標籤. 在 userMap 中配置如下:
<id property="id" column="id"/>
id 的唯一作用就是在嵌套的映射配置時判斷數據相同.
-
-
鑑別器映射:
``` <resultMap id="userRoleMapChoose" resultType="study.User"> <discriminator column="enabled" javaType="int"> <case value="1" resultMap="uesrRoleMap"/> <case value="0" resultMap="userMap"/> </discriminator> </resultMap> <select id="selectUserAndRoleById" resultMap="userRoleMapChoose"> SELECT id, username, userEmail, <!--注意這裏的別名--> role.id AS "role.id", <!--注意這裏的別名--> role.role_name AS "role.roleName" FROM user INNER JOIN user_role ON user_role.role_id = user.id INNER JOIN role ON role.id = user_role.role_id WHERE user.id = #{id} </select> ```
當用戶的 enabled 值爲 1 的時候表示用戶被啓用, 0 的時候表示用戶不可用. 當用戶可用時, 使用 userRoleMap 映射, 可以獲取到用戶信息和角色信息; 當用戶不可以用時, 使用 userMap 只能獲取到用戶信息.
-
參考:
[1] : MyBatis從入門到精通
Mybatis-高級映射
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.