MyBatis Series (IX): MyBatis advanced mapping results of one mapping

This blog mainly on three ways to achieve results MyBatis one to one mapping:

  1. Use an alias for automatic mapping
  2. Use resultMap Configuration
  3. The association tag configuration using resultMap

1. Automatic mapping alias

Assuming that there is such a demand: Gets the role the user has at the same time according to user queries the user id information, for example, we assume that a user can have only one role (the actual situation is certainly not the case).

In general, it is not recommended to directly modify database tables corresponding entity class, so here we New Class SysUserExtend, SysUser it inherits from class and adds SysRole type field as follows:

package com.zwwhnly.mybatisaction.model;

import java.util.List;

public class SysUserExtend extends SysUser {
    /**
     * 用户角色
     */
    private SysRole sysRole;

    public SysRole getSysRole() {
        return sysRole;
    }

    public void setSysRole(SysRole sysRole) {
        this.sysRole = sysRole;
    }
}

Then, we add the following method in the interface SysUserMapper:

/**
 * 根据用户id获取用户信息和用户的角色信息
 *
 * @param id
 * @return
 */
SysUserExtend selectUserAndRoleById(Long id);

Then, add the following code in the corresponding SysUserMapper.xml:

<select id="selectUserAndRoleById" resultType="com.zwwhnly.mybatisaction.model.SysUserExtend">
    SELECT u.id,
           u.user_name userName,
           u.user_password userPassword,
           u.user_email userEmail,
           u.create_time createTime,
           r.id "sysRole.id",
           r.role_name   "sysRole.roleName",
           r.enabled "sysRole.enabled",
           r.create_by   "sysRole.createBy",
           r.create_time "sysRole.createTime"
    FROM sys_user u
    INNER JOIN sys_user_role ur ON u.id = ur.user_id
    INNER JOIN sys_role r ON ur.role_id = r.id
    WHERE u.id = #{id}
</select>

Here to be noted that two points, the first point is resultType here, just to be arranged SysUserExtend new class, the second point is the alias for the column to be arranged "sysRole.id"in the format, and wherein sysRole to SysUserExtend class field names consistent to id field names SysRole and class consistency.

Finally, add the following test method SysUserMapperTest test class:

@Test
public void testSelectUserAndRoleById() {
    SqlSession sqlSession = getSqlSession();

    try {
        SysUserMapper sysUserMapper = sqlSession.getMapper(SysUserMapper.class);

        // 注意这里使用1001这个用户,因为这个用户只有1个角色
        SysUserExtend sysUserExtend = sysUserMapper.selectUserAndRoleById(1001L);

        Assert.assertNotNull(sysUserExtend);
        Assert.assertNotNull(sysUserExtend.getSysRole());
    } finally {
        sqlSession.close();
    }
}

Run the test code, the test passes, outputting the log follows:

DEBUG [main] - ==> Preparing: SELECT u.id, u.user_name userName, u.user_password userPassword, u.user_email userEmail, u.create_time createTime, r.id “sysRole.id”, r.role_name “sysRole.roleName”, r.enabled “sysRole.enabled”, r.create_by “sysRole.createBy”, r.create_time “sysRole.createTime” FROM sys_user u INNER JOIN sys_user_role ur ON u.id = ur.user_id INNER JOIN sys_role r ON ur.role_id = r.id WHERE u.id = ?

DEBUG [main] - ==> Parameters: 1001(Long)

TRACE [main] - <== Columns: id, userName, userPassword, userEmail, createTime, sysRole.id, sysRole.roleName, sysRole.enabled, sysRole.createBy, sysRole.createTime

TRACE [main] - <== Row: 1001, test, 123456, [email protected], 2019-06-27 18: 21: 07.0, 2, ordinary users, 1, 1, 2019-06-27 18:21 : 12.0

DEBUG [main] - <== Total: 1

2. Use the configuration resultMap

Extension of the above requirements, but replaced resultMap to configure mappings.

First, we add the following method in the interface SysUserMapper:

/**
 * 根据用户id获取用户信息和用户的角色信息
 *
 * @param id
 * @return
 */
SysUserExtend selectUserAndRoleByIdResultMap(Long id);

Then the corresponding first add the following SysUserMapper.xml resultMap:

<resultMap id="userRoleMap" type="com.zwwhnly.mybatisaction.model.SysUserExtend">
        <id property="id" column="id"/>
        <result property="userName" column="user_name"/>
        <result property="userPassword" column="user_password"/>
        <result property="userEmail" column="user_email"/>
        <result property="userInfo" column="user_info"/>
        <result property="headImg" column="head_img" jdbcType="BLOB"/>
        <result property="createTime" column="create_time" jdbcType="TIMESTAMP"/>
        <!--role相关属性-->
        <result property="sysRole.id" column="role_id"/>
        <result property="sysRole.roleName" column="role_role_name"/>
        <result property="sysRole.enabled" column="role_enabled"/>
        <result property="sysRole.createBy" column="role_create_by"/>
        <result property="sysRole.createTime" column="role_create_time" jdbcType="TIMESTAMP"/>
</resultMap>

In order to avoid multiple tables have the same column name, so when you configure role-related attributes, such as unified prefixed with "role_" Here, here's a column alias to query below and set consistent:

<select id="selectUserAndRoleByIdResultMap" resultMap="userRoleMap">
    SELECT  u.id,
            u.user_name,
            u.user_password,
            u.user_email,
            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_time
    FROM sys_user u
    INNER JOIN sys_user_role ur ON u.id = ur.user_id
    INNER JOIN sys_role r ON ur.role_id = r.id
    WHERE u.id = #{id}
</select>

Note: This query, we use the resultMap instead resultType.

Since the test code and outputs 1 and logs are almost the same, so there is no longer listed.

Some students may remember we had previously configured in such a resultMap SysUserMapper.xml in:

<resultMap id="sysUserMap" type="com.zwwhnly.mybatisaction.model.SysUser">
    <id property="id" column="id"/>
    <result property="userName" column="user_name"/>
    <result property="userPassword" column="user_password"/>
    <result property="userEmail" column="user_email"/>
    <result property="userInfo" column="user_info"/>
    <result property="headImg" column="head_img" jdbcType="BLOB"/>
    <result property="createTime" column="create_time" jdbcType="TIMESTAMP"/>
</resultMap>

Then you will think, we just userRoleMap defined, and the first half of this configuration are the same, can reuse this sysUserMap allocation?

The answer of course is, MyBatis supports resultMap mapping inheritance.

Therefore, userRoleMap can be inherited from sysUserMap, out duplicate configurations will be omitted, the optimized configuration as follows:

<resultMap id="userRoleMap" type="com.zwwhnly.mybatisaction.model.SysUserExtend" extends="sysUserMap">
    <!--role相关属性-->
    <result property="sysRole.id" column="role_id"/>
    <result property="sysRole.roleName" column="role_role_name"/>
    <result property="sysRole.enabled" column="role_enabled"/>
    <result property="sysRole.createBy" column="role_create_by"/>
    <result property="sysRole.createTime" column="role_create_time" jdbcType="TIMESTAMP"/>
</resultMap>

3. Use the tab to configure resultMap of association

The above configuration can also be used to configure the association tag, as shown configuration (the effect achieved is the same):

<resultMap id="userRoleMap" type="com.zwwhnly.mybatisaction.model.SysUserExtend" extends="sysUserMap">
    <association property="sysRole" columnPrefix="role_" javaType="com.zwwhnly.mybatisaction.model.SysRole">
        <result 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"/>
    </association>
</resultMap>

The idea of ​​the students may feel, role mapping configuration table completely independent configuration ah, like this:

<resultMap id="roleMap" type="com.zwwhnly.mybatisaction.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>

Then a powerful MyBatis allows association tag to use roleMap directly, so the above association tag configuration can be optimized for:

<resultMap id="userRoleMap" type="com.zwwhnly.mybatisaction.model.SysUserExtend" extends="sysUserMap">
    <association property="sysRole" columnPrefix="role_"
                     resultMap="roleMap"/>
</resultMap>

At this point, we are roleMap SysUserMapper.xml built in, but the actual use, this roleMap into SysRoleMapper.xml will be more reasonable.

Note, however, that the roleMap moved to the SysRoleMapper.xml, and use a full name when referencing roleMap, as follows:

<association property="sysRole" columnPrefix="role_"
             resultMap="com.zwwhnly.mybatisaction.mapper.SysRoleMapper.roleMap"/>

Otherwise it will be reported as an error.

4. The reference source and

Source Address: https://github.com/zwwhnly/mybatis-action.git , welcome to download.

Liuzeng Hui "MyBatis from entry to the master."

The original is not easy, if that article can learn something, like a welcome point, a commentary on, off a note, this is my greatest motivation insist on writing.

If you are interested, please add my micro letter: zwwhnly , waiting for you to talk technology, workplace, work and other topics (PS: I am a programmer struggle in Shanghai).

Published 34 original articles · won praise 107 · views 20000 +

Guess you like

Origin blog.csdn.net/zwwhnly/article/details/103503044