关联映射概述

晓乎 / 2023-05-09 / 原文

关联映射关系

  在关系型数据库中,表与表之间存在着三种关联映射关系,分别为一对一关系、一对多关系和多对多关系。

     一对一关系:一个数据表中的一条记录最多可以和另一个数据表中的一条记录相关。例如,现实生活中学生与校园卡就属于一对一的关系,一个学生只能拥有一张校园卡,一张校园卡只能属于一个学生。

     一对多关系:主键数据表中的一条记录可以和另外一个数据表的多条记录相关。但另外一个数据表中的记录只能与主键数据表中的某一条记录相关。例如,现实中班级与学生的关系就属于一对多的关系,一个班级可以有很多学生,但一个学生只能属于一个班级。

    多对多关系:一个数据表中的一条记录可以与另外一个数据表任意数量的记录相关,另外一个数据表中的一条记录也可以与本数据表中任意数量的记录相关。例如,现实中学生与教师属于多对多的关系,一名学生可以由多名教师授课,一名教师可以为多名学生授课。

Java对象如何描述事物之间的关系

     数据表之间的关系实质上描述的是数据之间的关系,除了数据表,在Java中,还可以通过对象来描述数据之间的关系。通过Java对象描述数据之间的关系,其实就是使对象的属性与另一个对象的属性相互关联。

Java对象描述数据之间的关联映射关系有三种,分别是一对一、一对多和多对多。

一对一

  就是在本类中定义与之关联的类的对象作为属性,例如,A类中定义B类对象b作为属性,在B类中定义A类对象a作为属性。

一对多

  就是一个A类对象对应多个B类对象的情况,例如,定义在A类中,定义一个B类对象的集合作为A类的属性;在B类中,定义A类对象a作为B类的属性。

多对多

  在两个相互关联的类中,都可以定义多个与之关联的类的对象。例如,在A类中定义B类类型的集合作为属性,在B类中定义A类类型的集合作为属性。

代码实现

一对一查询

  掌握一对一查询,能够使用<association>元素处理一对一关联关系。

  在现实生活中,一对一关联关系是十分常见的。例如,一个人只能有一个身份证,同时一个身份证也只会对应一个人。人与身份证之间的关联关系如图。

 

  在MyBatis中,通过<association>元素来处理一对一关联关系。<association>元素提供了一系列属性用于维护数据表之间的关系。<association>元素属性如下:

  <association>元素是<resultMap>元素的子元素,它有两种配置方式,嵌套查询方式和嵌套结果方式,下面对这两种配置方式分别进行介绍。  

  a.嵌套查询方式:嵌套查询是指通过执行另外一条SQL映射语句来返回预期的复杂类型。

<association property="card" column="card_id" 
	javaType="com.itheima.pojo.IdCard"		 
select="com.itheima.mapper.IdCardMapper.findCodeById" />

   b.嵌套结果方式:嵌套结果是使用嵌套结果映射来处理重复的联合结果的子集。

<association property="card" 	javaType="com.itheima.pojo.IdCard">
    <id property="id" column="card_id" />
    <result property="code" column="code" />
</association>

案例:

以个人和身份证之间的一对一关联关系为例,对MyBatis中一对一关联关系的处理进行详细讲解。案例具体实现步骤如下。

(1)创建数据库:

CREATE DATABASE IF NOT EXISTS mybatis;
USE mybatis;
# 创建一个名称为tb_idcard的表
CREATE TABLE  tb_idcard( 
     id INT PRIMARY KEY AUTO_INCREMENT,
     CODE VARCHAR(18)
);
# 插入2条数据
INSERT INTO tb_idcard(CODE) VALUES('152221198711020624');
INSERT INTO tb_idcard(CODE) VALUES('152201199008150317');
# 创建一个名称为tb_person的表
CREATE TABLE  tb_person( 
     id INT PRIMARY KEY AUTO_INCREMENT,
     name VARCHAR(32),
     age INT,
     sex VARCHAR(8),
     card_id INT UNIQUE,     
     FOREIGN KEY(card_id) REFERENCES tb_idcard(id)
);
# 插入2条数据

INSERT INTO tb_person(name,age,sex,card_id) VALUES('Rose',22,' female',1);
INSERT INTO tb_person(name,age,sex,card_id) VALUES('jack',23,'male',2);

(2)持久化类IDCard类:创建持久化类IdCard,用于封装身份证属性。

public class IdCard {
	private Integer id;                 // 主键id
	private String code;              // 身份证号码
	// 省略getter/setter方法
	@Override
	public String toString() {
		return "IdCard [id=" + id + ", code=" + code + "]";
	}
}

持久化类Person类:创建持久化类Person,用于封装个人属性。

public class Person {
        private Integer id;             // 主键id
        private String name;         // 姓名
        private Integer age;          // 年龄
        private String sex;            // 性别
        private IdCard card;  	   // 人员关联的证件
        // 省略getter/setter方法,重写的toString()方法
}

(3)编写IdCardMapper.xml文件:创建身份证映射文件IdCardMapper.xml,并在映射文件中编写一对一关联映射查询的配置信息。

<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
    "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.itheima.mapper.IdCardMapper">
  <!-- 根据id查询证件信息 -->
  <select id="findCodeById" parameterType="Integer" resultType="IdCard">
	  SELECT * from tb_idcard where id=#{id}
  </select>
</mapper>

编写PersonMapper.xml文件:创建人员映射文件PersonMapper.xml,并在映射文件中编写一对一关联映射查询的配置信息。

<select id="findPersonById" parameterType="Integer" 	resultMap="IdCardWithPersonResult">
	SELECT * from tb_person where id=#{id}	
</select> <resultMap type="Person" id="IdCardWithPersonResult"> <id property="id" column="id" /> <result property="name" column="name" /> <result property="age" column="age" /> <result property="sex" column="sex" />      <association property="card" column="card_id" javaType="IdCard" select="com.itheima.mapper.IdCardMapper.findCodeById" /> </resultMap>

(4)引入映射文件:在核心配置文件mybatis-config.xml中,引入IdCardMapper.xml和PersonMapper.xml映射文件,并为com.itheima.pojo包下的所有实体类定义别名。 

<!-- 只展示了定义别名和mapping文件中配置新添加的部分-- >
<!--使用扫描包的形式定义别名 -->
<typeAliases>
	<package name="com.itheima.pojo" />
</typeAliases>
<mappers>
	<mapper resource="com/itheima/mapper/IdCardMapper.xml" />
	<mapper resource="com/itheima/mapper/PersonMapper.xml" />
</mappers>

(5)编写测试类:在测试类MyBatisTest中,编写测试方法findPersonByIdTest()。

public void findPersonByIdTest() {
        // 1、通过工具类获取SqlSession对象
        SqlSession session = MyBatisUtils.getSession();
        // 2.使用MyBatis嵌套查询的方式查询id为1的人的信息
        Person person = session.selectOne("com.itheima.mapper." 
                                   + "PersonMapper.findPersonById", 1);
        // 3、输出查询结果信息
        System.out.println(person);
        // 4、关闭SqlSession
        session.close();
}