-
一对一映射:
-
使用自动映射处理一对一关系:
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从入门到精通