这是Mybatis由浅入深的第4节,前三节传送门:
【Mybatis由浅入深 -01入门】
【Mybatis由浅入深 - 02增删改查CRUD】
【Mybatis由浅入深 - 03动态SQL】
前言
在之前的章节中, 我们并未对返回结果做任何关系映射,但依然工作的很好,那是因为我们的java类字段名与mysql列名是一致的。但实际情况是mysql命名规则是login_name, 但java中却是loginName, 这就引出了mybatis的一个很强大的元素结果映射:resultMap .
使用环境
以下为基础前置条件:请参考其它博文自行安装。
- JDK:1.8
- Maven: 3.6.3
- Mysql: 5.7 安装教程
创建Mysql测试表(与前3节的表不同)
CREATE TABLE `account` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`login_name` varchar(30) DEFAULT NULL,
`nick_name` varchar(30) DEFAULT NULL,
`age` tinyint(1) DEFAULT NULL,
`create_time` datetime DEFAULT NULL,
`update_time` datetime DEFAULT NULL,
`is_deleted` tinyint(1) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
insert into `account` VALUES (1,'gg', '天罡', 18, '2022-09-09 18:00:00', null, 0);
如果照搬查user表查询代码, 代码能运行正常吗? 我们来试一试
1. 接口
public interface AccountMapper {
Account selectById(int id);
}
2. 映射文件
<mapper namespace="com.tiangang.dao.mapper.AccountMapper">
<select id="selectById" resultType="com.tiangang.dao.po.Account">
select * from account where id = #{id}
</select>
</mapper>
3. 数据对象PO
public class Account {
private Integer id;
private String loginName;
private String nickName;
private Integer age;
private Date createTime;
private Date updateTime;
private Boolean isDeleted;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getLoginName() {
return loginName;
}
public void setLoginName(String loginName) {
this.loginName = loginName;
}
public String getNickName() {
return nickName;
}
public void setNickName(String nickName) {
this.nickName = nickName;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
public Date getUpdateTime() {
return updateTime;
}
public void setUpdateTime(Date updateTime) {
this.updateTime = updateTime;
}
public Boolean getIsDeleted() {
return isDeleted;
}
public void setIsDeleted(Boolean deleted) {
isDeleted = deleted;
}
@Override
public String toString() {
return "Account{" +
"id=" + id +
", loginName='" + loginName + '\'' +
", nickName='" + nickName + '\'' +
", age='" + age + '\'' +
", createTime=" + createTime +
", updateTime=" + updateTime +
", isDeleted=" + isDeleted +
'}';
}
}
4. 单元测试
@Test
public void selectByIdTest() {
MyBatisManager.executeMapperMethod(true, AccountMapper.class, (mapper -> {
Account account = mapper.selectById(1);
System.out.println(account);
}));
}
结果不出所料,是有问题的,如下图:
结果显示,所有字段名与数据库不一致的字段,都没有取到正确的值,都为null了。这就对了,因为mysql列名与java类字段名不一致!
接着我们通过resultMap 来解决这个问题。
- 添加一个resultMap元素
property:指的是java类字段名
column:指的是数据库列名 - 将select元素的resultType修改为resultMap
<mapper namespace="com.tiangang.dao.mapper.AccountMapper">
<resultMap id="AccountResultMap" type="com.tiangang.dao.po.Account">
<id property="id" column="id" />
<result property="loginName" column="login_name"/>
<result property="nickName" column="nick_name"/>
<result property="age" column="age"/>
<result property="createTime" column="create_time"/>
<result property="updateTime" column="update_time"/>
<result property="isDeleted" column="is_deleted"/>
</resultMap>
<select id="selectById" resultMap="AccountResultMap">
select * from account where id = #{id}
</select>
</mapper>
请看正确的运行结果: