2024-12-22  阅读(300)
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 本文链接:https://www.skjava.com/mianshi/baodian/detail/4178883496

回答

Mybatis 中可以用 resultMap 中的<result>属性来映射以及 SQL 别名

CREATE TABLE t_user (
  id INT NOT NULL PRIMARY KEY,
  name VARCHAR(50),
  email VARCHAR(50)
)ENGINE=InnoDB;
public class User {
    private Integer userId;
    private String userName;
    private String userEmail;
    // getters and setters
}
  • 第一种,SQL 语句中定义字段名的别名。
<select id="selectUserById" parameterType="int" resultType="com.damingge.domain.User">
       select id as userId, name as userName, email as userEmail 
       form t_user where id = #{id};
</select>
  • 第二种,<result>标签映射字段名和实体类属性名
<mapper namespace="com.damingge.mapper.UserMapper">
  <resultMap id="UserResultMap" type="com.damingge.domain.User">
    <id property="userId" column="id"/>
    <result property="userName" column="name"/>
    <result property="userEmail" column="email"/>
  </resultMap>

  <select id="selectUserById" resultMap="userResultMap">
    SELECT id, name, email FROM t_user WHERE id = #{id}
  </select>
</mapper>

扩展

基本字段的映射可以按上述方法处理,对于 JSON 字符串字段如何转换为 Map?

TypeHandler

Mybatis 提供TypeHandler 接口支持自定义参数的设置和获取过程,实现特殊的字段扩展。

public class JsonTypeHandler extends BaseTypeHandler<Map<String, Object>> {

    // json 字符串解析
    private final ObjectMapper objectMapper = new ObjectMapper();

    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, Map<String, Object> parameter, JdbcType jdbcType) throws SQLException {
        // db 赋值 java_type -> jdbc_type
        ps.setString(i, objectMapper.writeValueAsString(parameter));
    }

    @Override
    public Map<String, Object> getNullableResult(ResultSet rs, String columnName) throws SQLException {
        // 从 db 取值 jdbc_type -> java_type
        return objectMapper.readValue(rs.getString(columnName), new TypeReference<Map<String, Object>>() {});
    }

    @Override
    public Map<String, Object> getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
        return objectMapper.readValue(rs.getString(columnIndex), new TypeReference<Map<String, Object>>() {});
    }

    @Override
    public Map<String, Object> getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
        return objectMapper.readValue(cs.getString(columnIndex), new TypeReference<Map<String, Object>>() {});
    }
}
<mapper namespace="com.damingge.mapper.UserMapper">

   <resultMap id="UserResultMap" type="com.damingge.domain.User">
        <id property="userId" column="id"/>
        <result property="userName" column="name"/>
        <result property="userEmail" column="email"/>
        <result property="extraInfo" column="extra_info" typeHandler="com.damingge.typehandler.JsonTypeHandler"/>
    </resultMap>

    <select id="selectUserById" resultMap="UserResultMap">
        SELECT id, name, email, extra_info FROM t_users WHERE user_id = #{id}
    </select>

</mapper>
public class User {
    private Integer userId;
    private String userName;
    private String userEmail;
    private Map<String, Object> extraInfo;
    // getters and setters
}

如上,通过自定义的 JsonTypeHandler 将 JSON 字符串字段 extra_info映射到实体类中的一个 Map 类型的属性。

枚举字段映射

再者,Mybatis 也可以自定义TypeHandler实现 Enum 枚举类映射 。

  • 用户表(t_user)结构
CREATE TABLE t_user (
  id INT NOT NULL PRIMARY KEY,
  name VARCHAR(50),
  status VARCHAR(10)
)ENGINE=InnoDB;
  • User 实体类
public class User {
    private Integer id;
    private String name;
    private Status status;
    // Getters and setters
}

public enum Status {
    ACTIVE, // 启用
    INACTIVE; // 禁用
}
  • 自定义UserStatusTypeHandler处理status枚举类型映射。
public class StatusTypeHandler extends BaseTypeHandler<Status> {

    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, Status parameter, JdbcType jdbcType) throws SQLException {
        // 赋值 java_type -> jdbc_type
        ps.setString(i, parameter.name());
    }

    @Override
    public Status getNullableResult(ResultSet rs, String columnName) throws SQLException {
        String status = rs.getString(columnName);
        // 取值 jdbc_type -> java_type
        return status == null ? null : Status.valueOf(status);
    }

    @Override
    public Status getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
        String status = rs.getString(columnIndex);
        return status == null ? null : Status.valueOf(status);
    }

    @Override
    public Status getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
        String status = cs.getString(columnIndex);
        return status == null ? null : Status.valueOf(status);
    }
}
  • Mapper XML 文件配置
<mapper namespace="com.damingge.mapper.UserMapper">
    <resultMap id="UserResultMap" type="com.damingge.domain.User">
        <id property="id" column="id"/>
        <result property="name" column="name"/>
        <result property="status" column="status" typeHandler="com.damingge.typehandler.UserStatusTypeHandler"/>
    </resultMap>

    <select id="selectUserById" resultMap="userResultMap">
        SELECT id, name, status FROM t_user WHERE id = #{id}
    </select>

    <insert id="insertUser">
        INSERT INTO t_user (name, status) VALUES (#{name}, #{status, typeHandler=com.damingge.typehandler.UserStatusTypeHandler})
    </insert>
</mapper>

Java 面试宝典是大明哥全力打造的 Java 精品面试题,它是一份靠谱、强大、详细、经典的 Java 后端面试宝典。它不仅仅只是一道道面试题,而是一套完整的 Java 知识体系,一套你 Java 知识点的扫盲贴。

它的内容包括:

  • 大厂真题:Java 面试宝典里面的题目都是最近几年的高频的大厂面试真题。
  • 原创内容:Java 面试宝典内容全部都是大明哥原创,内容全面且通俗易懂,回答部分可以直接作为面试回答内容。
  • 持续更新:一次购买,永久有效。大明哥会持续更新 3+ 年,累计更新 1000+,宝典会不断迭代更新,保证最新、最全面。
  • 覆盖全面:本宝典累计更新 1000+,从 Java 入门到 Java 架构的高频面试题,实现 360° 全覆盖。
  • 不止面试:内容包含面试题解析、内容详解、知识扩展,它不仅仅只是一份面试题,更是一套完整的 Java 知识体系。
  • 宝典详情:https://www.yuque.com/chenssy/sike-java/xvlo920axlp7sf4k
  • 宝典总览:https://www.yuque.com/chenssy/sike-java/yogsehzntzgp4ly1
  • 宝典进展:https://www.yuque.com/chenssy/sike-java/en9ned7loo47z5aw

目前 Java 面试宝典累计更新 400+ 道,总字数 42w+。大明哥还在持续更新中,下图是大明哥在 2024-12 月份的更新情况:

想了解详情的小伙伴,扫描下面二维码加大明哥微信【daming091】咨询

同时,大明哥也整理一套目前市面最常见的热点面试题。微信搜[大明哥聊 Java]或扫描下方二维码关注大明哥的原创公众号[大明哥聊 Java] ,回复【面试题】 即可免费领取。

阅读全文