【MyBatis07】MyBatis处理关联关系(多表连接):一对一

表格之间可以通过外键建立关联,表对应的实体之间也有一定的关系,这种关系成为关联关系。

关联关系实际上是“有”(has)和“从属于”(belong)的关系,例如:护照从属于某个旅客,旅客拥有自己的护照

关联关系主要有以下三大类:

  • OneToOne:一对一关系

  • OneToMany:一对多关系

  • ManyToMany:多对多关系

处理具有关联关系的表的操作无非仍旧是“增删改查”操作,其中“增删改”操作与没有关联关系的表并无太大的区别,主要需要特别关注查询操作。

1 一对一关系

1.1 数据准备

  • 建表:

CREATE TABLE t_passengers(
    id INT PRIMARY KEY AUTO_INCREMENT,
    NAME VARCHAR(50),
    sex VARCHAR(1),
    birthday DATE
)DEFAULT CHARSET =utf8;

CREATE TABLE t_passports(
    id INT PRIMARY KEY AUTO_INCREMENT,
    nationality VARCHAR(50),
    expire DATE,
    passenger_id INT UNIQUE,
    FOREIGN KEY (passenger_id) REFERENCES t_passengers(id)
)DEFAULT CHARSET =utf8;
  • 插入测试数据:
INSERT INTO t_passengers VALUES(NULL,'SuzuMiya Haruhi','f','2018-11-11');
INSERT INTO t_passengers VALUES(NULL,'Kyo','m','2019-12-12');

INSERT INTO t_passports VALUES(NULL,'Universe','2030-12-12',1);
INSERT INTO t_passports VALUES(NULL,'Japan','2035-12-12',2);

 

 

  • 建立对应实体:

Passenger:

public class Passenger {
    private Integer id;
    private String name;
    private Boolean sex;
    private Date birthday;

    public Passenger() {
    }
    ......

Passport:

 

public class Passport {
    private Integer id;
    private String nationality;
    private Date expire;

    public Passport() {
    }
    ......

1.2 添加关系属性

实体建立完毕以后发现,Passenger类虽然可以存储旅客相关的信息,但不能存储其拥有的护照属性;同样的,Passport类虽然可以存储护照的相关信息,但是不能存储其所属的旅客属性。此时实体和表之间还不是一个等价的对应关系。

于是,我们需要在两个类分别中加入关系属性,使两个实体类之间建立起关联。

Passenger:

public class Passenger {
    private Integer id;
    private String name;
    private Boolean sex;
    private Date birthday;

    private Passport passport;//存储旅客的护照信息

    public Passenger() {
    }
    ......

Passport:

 

public class Passport {
    private Integer id;
    private String nationality;
    private Date expire;

    private Passenger passenger;//存储护照所属的旅客信息

    public Passport() {
    }
    ......

1.3 进行关联查询

DAO接口:

//通过旅客id查询旅客信息(包括其护照的相关信息)
Passenger queryPassengerById(@Param("id") Integer id);

进行查询得到的列有7列,而Passenger类只有五个属性,因此需要用到resultMap来自定义映射规则。

Mapper.xml:

    <resultMap id="passenger_passport" type="Passenger">
        <id column="id" property="id"/>
        <result column="name" property="name"/>
        <result column="sex" property="sex"/>
        <result column="birthday" property="birthday"/>
        <!--描述passId nationality expire 三列和passport 实体属性之间的关系-->
        <association property="passport" javaType="Passport">
            <id column="passId" property="id"/>
            <result column="nationality" property="nationality"/>
            <result column="expire" property="expire"/>
        </association>
    </resultMap>
    
    <select id="queryPassengerById" resultMap="passenger_passport">
        SELECT t_passengers.id,t_passengers.name,t_passengers.sex,t_passengers.birthday,
               t_passports.id passId,t_passports.nationality,t_passports.expire
        FROM t_passengers JOIN t_passports
        ON t_passengers.id = t_passports.passenger_id
        WHERE t_passengers.id=#{id};
    </select>
  • <association property="passport" javaType="Passport">

    • 此处的property属性与上面四个 result 标签的property一致,属于Passenger

  • <id column="passId" property="id"/>

    • 此处的property属于Passport

测试:

        PassengerDao passengerMapper = MyBatisUtil.getMapper(PassengerDao.class);
        Passenger passenger = passengerMapper.queryPassengerById(1);
        System.out.println(passenger);

测试结果:

Passenger{id=1, name='SuzuMiya Haruhi', sex=false, birthday=Sun Nov 11 00:00:00 CST 2018, passport=Passport{id=1, nationality='Universe', expire=Thu Dec 12 00:00:00 CST 2030, passenger=null}}

注意:记得注册Mapper文件

<!--注册Mapper文件-->
    <mappers>
......
        <mapper resource="PassengerDAOMapper.xml"/>
    </mappers>

1.4 双向查询

通过Passport去关联查询Passenger,流程和前述一致(完全对称),此处不再赘述,仅展示Mapper.xml:

<?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.qianglj.test2.dao.PassportDao">
    <resultMap id="passport_passenger" type="Passport">
        <id property="id" column="id"/>
        <result property="nationality" column="nationality"/>
        <result property="expire" column="expire"/>

        <association property="passenger" javaType="Passenger">
            <id property="id" column="passenger_id"/>
            <result property="name" column="name"/>
            <result property="sex" column="sex"/>
            <result property="birthday" column="birthday"/>
        </association>
    </resultMap>
    <select id="queryPassportById" resultMap="passport_passenger">
        SELECT t_passports.id,t_passports.nationality,t_passports.expire,
                t_passengers.id passenger_id,t_passengers.name,t_passengers.sex,t_passengers.birthday
        FROM t_passports JOIN t_passengers
        ON t_passports.passenger_id = t_passengers.id
        WHERE t_passports.id=#{id};
    </select>
</mapper>

 

 

 

版权声明:
作者:jackqiang
链接:http://www.jackqiang.com/framework/mybatis/1942/one2one/
来源:JackQiang's
文章版权归作者所有,未经允许请勿转载。

THE END
分享
二维码
< <上一篇
下一篇>>
文章目录
关闭
目 录