数据库对象中出现复杂的对象嵌套,如何使用Mybatis plus优雅的解决这个问题:

发布于:2024-07-27 ⋅ 阅读:(29) ⋅ 点赞:(0)

起因

类原型:
在User类:

package com.itheima.mp.domain.po;

import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.IdType;
import java.time.LocalDateTime;
import com.baomidou.mybatisplus.annotation.TableId;
import java.sql.Blob;
import java.io.Serializable;

import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.itheima.mp.enums.UserStatus;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;

/**
 * <p>
 * Users and global privileges
 * </p>
 *
 * @author lgq
 * @since 2024-07-21
 */
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName(value = "user", autoResultMap = true)
@ApiModel(value="User对象", description="Users and global privileges")
/**
 * 下面的对象之间是有嵌套的,User中嵌套了UserInfo对象。
 * 对于这种情况,我们要定义复杂的ResultMap,但是这里不想定义,所以在TableName注解中加入autoResultMap=true就可以自动实现。
 */
public class User implements Serializable {

    private static final long serialVersionUID = 1L;
    /**
     * 用户id
     */
    private Long id;

    /**
     * 用户名
     */
    private String username;

    /**
     * 密码
     */
    private String password;

    /**
     * 注册手机号
     */
    private String phone;

    /**
     * 详细信息
     */
    @TableField(typeHandler = JacksonTypeHandler.class)
    private UserInfo info;

    /**
     * 使用状态(1正常 2冻结)
     */
    private UserStatus status;

    /**
     * 账户余额
     */
    private Integer balance;

    /**
     * 创建时间
     */
    private LocalDateTime createTime;

    /**
     * 更新时间
     */
    private LocalDateTime updateTime;
    //
    // @TableId(value = "Host", type = IdType.AUTO)
    // private String Host;

}

User类中嵌套了UserInfo类:

package com.itheima.mp.domain.po;

import lombok.Data;

@Data
public class UserInfo {
    private Integer age;
    private String intro;
    private String gender;

}

在处理时,将UserInfo对象通过JacksonTypeHandler将Json转为String类型并保存在里数据库中。然而,当读取时,始终读取不到info信息:
在这里插入图片描述
读取到的信息为:

User(id=309589, username=NewUs0er, password=12345, phone=1234567890, info=null, status=NORMAL, balance=null, createTime=2024-07-22T23:04:35, updateTime=2024-07-22T23:04:35)
info = null

发现原因:

由于对象里嵌套了复杂的对象,这里我们并没有实现ResultMap的映射,所以无法将String类型的Json字符串转为正确的对象。这里需要在User类中加入autoResultMap注解:
在这里插入图片描述
如果不这么做,使用默认的传统的在xml文件中编写sql,那sql就会变得很复杂:

<mapper namespace="com.example.mapper.UserMapper">
    <!-- ResultMap for User -->
    <resultMap id="userResultMap" type="com.example.domain.User">
        <id property="id" column="id" />
        <result property="username" column="username" />
        
        <!-- Association for nested UserInfo object -->
        <association property="userInfo" javaType="com.example.domain.UserInfo">
            <id property="id" column="user_info_id" />
            <result property="age" column="age" />
            <result property="intro" column="intro" />
            <result property="gender" column="gender" />
        </association>
    </resultMap>

    <!-- Select statement to fetch User along with UserInfo -->
    <select id="selectUserById" resultMap="userResultMap">
        SELECT u.id, u.username, 
               ui.id as user_info_id, ui.age, ui.intro, ui.gender
        FROM user u
        LEFT JOIN user_info ui ON u.id = ui.user_id
        WHERE u.id = #{id}
    </select>
</mapper>


网站公告

今日签到

点亮在社区的每一天
去签到