Mybatis高级映射-SELECT-一对一

概述

本章学习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高级映射-SELECT-一对一

通过结果日志可知,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接口与测试类同上,测试结果如下:

Mybatis高级映射-SELECT-一对一

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,共同学习、共同进步,谢谢!

Mybatis高级映射-SELECT-一对一

相关推荐