关联关系概述
在关系型数据库中,多表之间存在着三种关联关系,分别为一对一、一对多和多对多,如图所示。

这三种关联关系的具体说明如下。
· 一对一:在任意一方引入对方主键作为外键。
· 一对多:在“多”的一方,添加“一”的一方的主键作为外键。
· 多对多:产生中间关系表,引入两张表的主键作为外键,两个主键成为联合主键或使用新的字段作为主键。
通过数据库中的表可以描述数据之间的关系,同样,在Java中,通过对象也可以进行关系描述,如图所示。

三种关联关系的描述如下。
· 一对一的关系:就是在本类中定义对方类型的对象,如A类中定义B类类型的属性b, B类中定义A类类型的属性a。
· 一对多的关系:就是一个A类类型对应多个B类类型的情况,需要在A类中以集合的方式引入B类类型的对象,在B类中定义A类类型的属性a。
· 多对多的关系:在A类中定义B类类型的集合,在B类中定义A类类型的集合。
以上就是Java对象中,三种实体类之间的关联关系,那么使用MyBatis是如何处理Java对象中的三种关联关系呢?在接下来的3个小节中,将对MyBatis中的这几种关联关系的使用进行详细讲解。
一、一对一
在现实生活中一对一很常见,例如一个人只能有一个身份证。同时一个身份证也只会对应一个人,他们的关系模型如下:

那么使用MyBatis是怎么处理图中的这种一对一关联关系的呢?在本书第7章所讲解的<resultMap>元素中,包含了一个<association>子元素,MyBatis就是通过该元素来处理一对一关联关系的。
在<association>元素中,通常可以配置以下属性。
· property:指定映射到的实体类对象属性,与表字段一一对应。
· column:指定表中对应的字段。
· javaType:指定映射到实体对象属性的类型。
· select:指定引入嵌套查询的子SQL语句,该属性用于关联映射中的嵌套查询。
· fetchType:指定在关联查询时是否启用延迟加载。fetchType属性有lazy和eager两个属性值,默认值为lazy(即默认关联映射延迟加载)。
<association>元素的使用非常简单,只需要参考如下两种示例配置即可,
<! --方式一:嵌套查询-->
<association property="card" column="card_id"
javaType="com.xxx.po.IdCard"
select="com.xxx.mapper.IdCardMapper.findCodeById" />
<! --方式二:嵌套结果-->
<association property="card" javaType="com.xxx.po.IdCard">
<id property="id" column="card_id" />
<result property="code" column="code" />
</association>
解了MyBatis中处理一对一关联关系的元素和方式后,接下来就以个人和身份证之间的一对一关联关系为例,进行详细讲解。
查询个人及其关联的身份证信息是先通过查询个人表中的主键来获个人信息,然后通过表中的外键,来获取证件表中的身份证号信息。其具体实现步骤如下。
(1)创建数据表。在mybatis数据库中分别创建名为tb_idcard和tb_person的数据表,同时预先插入两条数据。其执行的SQL语句如下所示。
mysql> create table tb_idcard(id int primary key auto_increment,code varchar(18));
mysql> insert tb_idcard (code) values ('410821199302223519');
mysql> insert tb_idcard (code) values ('410821199302223520');
创建person表,加入2条数据
mysql> 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));
mysql> insert into tb_person (name,age,sex,card_id) values ('Roes',29,'女',1);
mysql> insert into tb_person (name,age,sex,card_id) values ('Jack',27,'男',2);
2.创建IdCard.java 及Person.java
package com.mkit.pojo;
public class IdCard {
private Integer id;
private String code;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
@Override
public String toString() {
return "IdCard [id=" + id + ", code=" + code + "]";
}
}
********************************************************
package com.mkit.pojo;
public class Person {
private Integer id;
private String name;
private Integer age;
private String sex;
private IdCard card;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public IdCard getCard() {
return card;
}
public void setCard(IdCard card) {
this.card = card;
}
@Override
public String toString() {
return "Person [id=" + id + ", name=" + name + ", age=" + age + ", sex=" + sex + ", card=" + card + "]";
}
}
3.编写IdCardMapper.xml及PersonMapper.xml
-----------------------IdCardMapper.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.mkit.mapper.IdCardMapper">
<select id="findCodeById"
parameterType="Integer"
resultType="card">
select * from tb_idcard where id=#{id}
</select>
</mapper>
-----------------------PersonMapper.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.mkit.mapper.PersonMapper">
<select id="findPersonById" resultMap="IdCardWhitPersonResult">
select * from tb_person
where
id=#{id}
</select>
<resultMap type="Person" id="IdCardWhitPersonResult">
<id property="id" column="id" />
<result property="name" column="name" />
<result property="age" column="age" />
<result property="sex" column="sex" />
<result property="sex" column="sex" />
<association property="card" column="card_id"
javaType="card" select="com.mkit.mapper.IdCardMapper.findCodeById" />
</resultMap>
</mapper>
4.在核心配置文件mybatis-config.xml引入Mapper映射文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<properties resource="db.porperties" />
<typeAliases>
<typeAlias alias="card" type="com.mkit.pojo.IdCard" />
<typeAlias alias="person" type="com.mkit.pojo.Person" />
</typeAliases>
<environments default="mysql">
<environment id="mysql">
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="com/mkit/mapper/PersonMapper.xml" />
<mapper resource="com/mkit/mapper/IdCardMapper.xml" />
</mappers>
</configuration>
5.测试
public class MyBatisAssociatedTest {
@Test
public void findPersonById() {
SqlSession sqlSession = MyBatisUtils.getSqlSession();
if(sqlSession!=null) {
Person person = new Person();
person.setId(1);
Person.findPersonById(sqlSession,person);
}
}
}
-----------------------------------------------------------
public static void findPersonById(SqlSession sqlSession, Person person) {
Person personEnty=sqlSession.selectOne("com.mkit.mapper.PersonMapper.findPersonById", person.getId());
System.out.println(personEnty.toString());
sqlSession.close();
}

网友评论