概述
本章学习Mybatis查询的一对一关系的多种实现方式。
本系列文章是基于Mybatis 3.4.6 版本。
创建表
创建测试使用的数据库表,使用用户表和用户身份证表进行测试,用户表与身份证是一对一关系,创建表结构如下:
用户表:
CREATE TABLE `sys_user` (
`id` bigint(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键',
`user_account` varchar(50) COLLATE utf8_bin NOT NULL COMMENT '用户账户',
`user_password` char(32) COLLATE utf8_bin NOT NULL COMMENT 'MD5加密的用户密码',
`user_email` varchar(20) COLLATE utf8_bin DEFAULT NULL COMMENT '用户邮箱',
`user_phone` varchar(20) COLLATE utf8_bin DEFAULT NULL COMMENT '手机号',
`idcard_id` bigint(11) unsigned DEFAULT NULL COMMENT '身份证信息表ID',
`created_date` datetime NOT NULL COMMENT '创建时间',
`modified_date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
`yn` tinyint(1) unsigned NOT NULL DEFAULT '1' COMMENT '是否有效(0无效,1有效)',
`modified_user` varchar(50) COLLATE utf8_bin DEFAULT NULL COMMENT '修改人',
`remark` varchar(500) COLLATE utf8_bin DEFAULT NULL COMMENT '备注',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=21 DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='用户表';
用户身份证信息表:
CREATE TABLE `sys_user_idcard` (
`id` bigint(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键',
`user_name` varchar(50) COLLATE utf8_bin NOT NULL COMMENT '姓名',
`user_sex` tinyint(1) unsigned NOT NULL COMMENT '性别1:男 2:女',
`user_birthday` date NOT NULL COMMENT '出生日期',
`user_address` varchar(100) COLLATE utf8_bin DEFAULT NULL COMMENT '住址',
`idcard_no` varchar(18) COLLATE utf8_bin NOT NULL COMMENT '身份证号码',
`issuing_authority` varchar(50) COLLATE utf8_bin DEFAULT NULL COMMENT '签发机关',
`indate_start` date DEFAULT NULL COMMENT '有效期开始日期',
`indate_end` date DEFAULT NULL COMMENT '有效期结束日期',
`created_date` datetime NOT NULL COMMENT '创建时间',
`modified_date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
`yn` tinyint(1) unsigned NOT NULL DEFAULT '1' COMMENT '是否有效(0无效,1有效)',
`modified_user` varchar(50) COLLATE utf8_bin DEFAULT NULL COMMENT '修改人',
`remark` varchar(500) COLLATE utf8_bin DEFAULT NULL COMMENT '备注',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=21 DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='身份证信息表';
自动映射
通过数据库表关系,我们在sys_user表中添加了外键列,关联sys_user_idcard表主键,所有在创建实体时,在SysUser类中增加SysUserIdcard属性,实体类代码如下:
SysUser:
package com.github.dalianghe.model;
import com.github.dalianghe.mapper.SysUserIdcardModel;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
@Setter
@Getter
@ToString
public class SysUserModel{
/** 用户账户 */
private String userAccount;
/** 用户密码 */
private String userPassword;
/** 用户身份证信息 */
private SysUserIdcardModel idcard;
}
SysUserIdcard:
package com.github.dalianghe.model;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import java.time.LocalDate;
@Setter
@Getter
@ToString
public class SysUserIdcardModel{
/** 用户姓名 */
private String userName;
/** 出生日期 */
private LocalDate userBirthday;
/** ... 省略其他属性 ...*/
}
注意:本例子我们使用了JSR310规范(如:LocalDate),故需在pom文件中添加依赖,如下:
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-typehandlers-jsr310</artifactId>
<version>1.0.2</version>
</dependency>
mapper映射文件配置如下:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.github.dalianghe.mapper.SysUserMapper">
<select id="selectSysUserById" parameterType="java.lang.Long"
resultType="com.github.dalianghe.model.SysUserModel">
SELECT user_account, user_password,
<!-- idcard为实体中定义的属性,表示SysUserIdcard对象,再通过"."访问其属性,Mybatis自动映射 -->
user_name "idcard.user_name",
user_birthday "idcard.user_birthday"
FROM sys_user t1, sys_user_idcard t2
WHERE t1.idcard_id = t2.id
AND t1.id=#{id}
</select>
</mapper>
Mapper接口代码如下:
package com.github.dalianghe.mapper;
import com.github.dalianghe.model.SysUserModel;
public interface SysUserMapper {
SysUserModel selectSysUserById(Long id) throws Exception;
}
测试方法代码如下:
@Test
public void testSelectSysUserById(){
SqlSession sqlSession = getSqlSession();
try{
SysUserMapper sysUserMapper = sqlSession.getMapper(SysUserMapper.class);
SysUserModel user = sysUserMapper.selectSysUserById(20L);
System.out.println("按用户ID查询用户信息:" + user.toString());
//sqlSession.commit();
}catch (Exception e){
e.printStackTrace();
//sqlSession.rollback();
}finally {
sqlSession.close();
}
}
结果如下:
通过结果日志可知,Mybatis自动将关联的身份证信息通过属性映射到用户对象中。
resultMap映射
对于查询可通过resultMap进行属性和列进行映射,此一对一mapper配置文件如下:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.github.dalianghe.mapper.SysUserMapper">
<!-- 配置resultMap,将实体属性与sql字段进行对应 -->
<resultMap id="SysUserMap" type="com.github.dalianghe.model.SysUserModel">
<id property="id" column="id"/>
<result property="userAccount" column="user_account"/>
<result property="userPassword" column="user_password"/>
<!--
idcard为SysUser属性,该属性为SysUserIdcard对象
以下两句意思为:将user_name和user_birthday查询字段的值映射到idcard对象的userName和userBirthday属性中
-->
<result property="idcard.userName" column="user_name"/>
<result property="idcard.userBirthday" column="user_birthday"/>
</resultMap>
<!--resultMap映射-->
<select id="selectSysUserById" parameterType="java.lang.Long" resultMap="SysUserMap">
SELECT user_account, user_password,
user_name, user_birthday
FROM sys_user t1, sys_user_idcard t2
WHERE t1.idcard_id = t2.id
AND t1.id=#{id}
</select>
</mapper>
Mapper接口与测试类同上,测试结果如下:
association映射
与resultMap映射类型,使用association标签进行映射,代码如下:
<resultMap id="SysUserMap" type="com.github.dalianghe.model.SysUserModel">
<id property="id" column="id"/>
<result property="userAccount" column="user_account"/>
<result property="userPassword" column="user_password"/>
<association property="idcard" javaType="com.github.dalianghe.model.SysUserIdcardModel">
<result property="userName" column="user_name"/>
<result property="userBirthday" column="user_birthday"/>
</association>
</resultMap>
association标签属性有:
- property:对应实体类中的属性名,必填项
- javaType:属性对应的java类型
- resultMap:可以使用resultMap,替换javaType
- columnPrefix:查询列名的前缀,配置后,在子标签配置result的column时可以省略前缀,但sql字段前缀或别名必须以此开头
测试用例与结果与上面一致。
总结
本文介绍了Mybatis一对一映射的三种方法,希望对大家有帮助。
最后创建了qq群方便大家交流,可扫描加入,同时也可加我qq:276420284,共同学习、共同进步,谢谢!
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。