回答
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] ,回复【面试题】 即可免费领取。