6.1 高级结果映射
6.1.1 一对一映射
6.1.1.1 使用自动映射处理一对一关系
6.1.1.2 使用resultMap配置一对一映射
6.1.1.3 使用resultMap的association标签配置一对一映射
在上面的配置上在做修改:
<resultMap id="userRoleMap" type="com.ql.simple.model.SysUser" extends="userMap"><association property="role" columnPrefix="role_" javaType="com.ql.simple.model.SysRole"><result property="id" column="role_id"/><result property="roleName" column="role_name"/><result property="enabled" column="enabled"/><result property="createTime" column="create_time" jdbcType="TIMESTAMP"/><result property="createBy" column="create_by"/></association></resultMap>
association标签的属性:
- property:对应实体类中的属性名
- javaType:属性对应的Java类型
- resultType
- resultMap
- columnPrefix
…
由于配置了columnPrefix=”role“,在写sql的时候,sys_role表相关的查询列的别名都要有“role”前缀,在内部result配置column时,需要配置成去掉前缀的列名
6.1.1.4 association标签嵌套查询
<resultMap id="userRoleMapSelect" type="com.ql.simple.model.SysUser" extends="userMap"><association property="role" column="{id=role_id}" select="com.ql.simple.mapper.RoleMapper.selectRoleById"></association></resultMap><select id="selectUserAndRoleByIdSelect" resultMap="userRoleMapSelect">select u.id,u.user_name,u.user_password,u.user_email,u.user_info,u.head_img,u.create_time,ur.role_idfrom sys_user uinner join sys_user_role ur on u.id = ur.user_idwhere u.id = #{id}</select>
<resultMap id="roleMap" type="com.ql.simple.model.SysRole"><id property="id" column="id"/><result property="roleName" column="role_name"/><result property="enabled" column="enabled"/><result property="createBy" column="create_by"/><result property="createTime" column="create_time" jdbcType="TIMESTAMP"/></resultMap><select id="selectRoleById" resultMap="roleMap">select * from sys_role where id = #{id}</select>
开启延迟加载:
这样只有在调用getRole的时候才会执行关于role的查询:
但根据debug发现并不是预想的那样,是因为mybatis的全局配置中有个参数为aggressiveLazyLoading,该参数默认为true,含义是,对任意延迟属性的调用会使带有延迟加载属性的对象完整加载,反之,每种属性都将按需加载
mybatis还有个参数lazyLoadTriggerMethods,当调用配置中的方法时,加载全部的延迟加载数据,默认值为“equals,clone,hashCode,toString”因此在默认情况下,只要调用其中一个方法就可以实现加载调用对象的全部数据
6.1.2 一对多映射
6.1.2.1 collection集合的嵌套结果映射
先对SysUser类进行修改:
/** 用户表* Created by ql on 2022/6/9*/@Datapublic class SysUser {private Long id;private String userName;private String userPassword;private String userEmail;private String userInfo;private byte[] headImg;private Date createTime;// private SysRole role;private List<SysRole> roleList;}
修改UserMapper.xml
<resultMap id="userRoleListMap" type="com.ql.simple.model.SysUser" extends="userMap"><collection property="roleList" columnPrefix="role_" resultMap="com.ql.simple.mapper.RoleMapper.roleMap"></collection></resultMap>
业务逻辑:
/*** 获取所有的用户以及对应的所有角色* @return*/List<SysUser> selectAllUserAndRoles();
<select id="selectAllUserAndRoles" resultMap="userRoleListMap">select u.id,u.user_name,u.user_password,u.user_email,u.user_info,u.head_img,u.create_time,r.id role_id,r.role_name role_role_name,r.enabled role_enabled,r.create_by role_create_by,r.create_time role_create_timefrom sys_user uinner join sys_user_role ur on u.id = ur.user_idinner join sys_role r on ur.role_id = r.id</select>
6.1.2.2 collection集合的嵌套查询
6.1.3 鉴别器映射
<resultMap id="rolePrivilegeListMapChoose" type="com.ql.simple.model.SysRole"><discriminator javaType="int" column="enabled"><case value="1" resultMap="rolePrivilegeListMapSelect"></case><case value="0" resultMap="roleMap"></case></discriminator></resultMap>
当enable为1的时候表示可用,这时使用rolePrivilegeListMapSelect映射,这是一个一对多的嵌套查询映射,可以获取到该角色下详细的权限信息
当角色被禁用时,只能获取角色的基本信息,不能获得角色的权限信息
<select id="selectRoleByUserIdChoose" resultMap="rolePrivilegeListMapChoose">select r.id,r.role_name,r.enabled,r.create_by,r.create_timefrom sys_role rinner join sys_user_role ur on ur.role_id = r.idwhere ur.user_id = #{userId}</select>
6.2 存储过程
6.2.1 第一个存储过程
<select id="selectUserById" statementType="CALLABLE" useCache="false">{call select_user_by_id(#{id,mode=IN},#{userName,mode=OUT,jdbcType=VARCHAR},#{userPassword,mode=OUT,jdbcType=VARCHAR},#{userEmail,mode=OUT,jdbcType=VARCHAR},#{userInfo,mode=OUT,jdbcType=VARCHAR},#{headImg,mode=OUT,jdbcType=BLOB,javaType=_byte[]},#{createTime,mode=OUT,jdbcType=TIMESTAMP})}</select>
/*** 使用存储过程查询用户信息* @param user*/void selectUserById(SysUser user);
- 需要把statementType设置为CALLABLE,由于存储过程方式不支持MyBatis的二级缓存,因此为了避免缓存配置出错,直接将select标签的useCache属性设置为false
- 必须指定参数的mode,可以为IN、OUT、INOUT
_byte表示的基本类型,Mybatis默认使用的是Byte类型
6.2.2 第二个存储过程
<select id="selectUserPage" statementType="CALLABLE" useCache="false" resultMap="userMap">{call select_user_page(#{userName,mode=IN},#{offset,mode=IN},#{limit,mode=IN},#{total,mode=OUT,jdbcType=BIGINT})}</select>
/*** 使用存储过程分页查询* @param params* @return*/List<SysUser> selectUserPage(Map<String, Object> params);
6.2.3 第三个和第四个存储过程
/*** 保存用户信息和角色关联信息* @param user* @param roleIds* @return*/int insertUserAndRoles(@Param("user") SysUser user, @Param("roleIds") String roleIds);/*** 根据用户id删除用户和用户的角色信息* @param id* @return*/int deleteUserById(Long id);
<insert id="insertUserAndRoles" statementType="CALLABLE">{call insert_user_and_roles(#{user.id,mode=OUT,jdbcType=BIGINT},#{user.userName,mode=IN},#{user.userPassword,mode=IN},#{user.userEmail,mode=IN},#{user.userInfo,mode=IN},#{user.headImg,mode=IN,jdbcType=BLOB},#{user.createTime,mode=OUT,jdbcType=TIMESTAMP},#{roleIds,mode=IN})}</insert><delete id="deleteUserById" statementType="CALLABLE">{call delete_user_by_id(#{id,mode=IN})}</delete>
6.3 使用枚举或其他对象
6.3.1 使用Mybatis提供的枚举处理器
/*** Created by ql on 2022/6/14*/public enum Enabled {disabled,enabled}

还得在mybatis-config中配置:<typeHandlers><typeHandler javaType="com.ql.simple.type.Enabled" handler="org.apache.ibatis.type.EnumOrdinalTypeHandler"/></typeHandlers>
6.3.2 使用自定义的类型处理器
public enum Enabled {disabled(1),enabled(0);private final int value;private Enabled(int value) {this.value = value;}public int getValue() {return value;}}
/*** Created by ql on 2022/6/14*/public class EnabledTypeHandler implements TypeHandler<Enabled> {private final Map<Integer, Enabled> enabledMap = new HashMap<Integer, Enabled>();public EnabledTypeHandler() {for (Enabled enabled : Enabled.values()) {enabledMap.put(enabled.getValue(), enabled);}}@Overridepublic void setParameter(PreparedStatement preparedStatement, int i, Enabled enabled, JdbcType jdbcType) throws SQLException {preparedStatement.setInt(i, enabled.getValue());}@Overridepublic Enabled getResult(ResultSet resultSet, String s) throws SQLException {int value = resultSet.getInt(s);return enabledMap.get(value);}@Overridepublic Enabled getResult(ResultSet resultSet, int i) throws SQLException {int value = resultSet.getInt(i);return enabledMap.get(value);}@Overridepublic Enabled getResult(CallableStatement callableStatement, int i) throws SQLException {int value = callableStatement.getInt(i);return enabledMap.get(value);}}
6.3.3 对Java8日期的支持
<dependency><groupId>org.mybatis</groupId><artifactId>mybatis-typehandlers-jsr310</artifactId><version>1.0.2</version></dependency>





