MyBatis的ResultMaps之一对一关系

1. 一对一关系

在我们domain的包中,每一个student都关联了一个地址。STUDENT的表中拥有ADDR_ID的列这个是作为ADDRESS表的外主键。

STUDENT表的信息如下:

MyBatis的ResultMaps之一对一关系_第1张图片

ADDRESS表的信息如下:


让我们来看一下如何通过获取Student信息包括Adress信息。

public class Address
{
private Integer addrId;
private String street;
private String city;
private String state;
private String zip;
private String country;
// setters & getters
}
public class Student
{
private Integer studId;
private String name;
private String email;
private PhoneNumber phone;
private Address address;
//setters & getters
}
<resultMap type="Student" id="StudentWithAddressResult">
<id property="studId" column="stud_id"/>
<result property="name" column="name"/>
<result property="email" column="email"/>
<result property="phone" column="phone"/>
<result property="address.addrId" column="addr_id"/>
<result property="address.street" column="street"/>
<result property="address.city" column="city"/>
<result property="address.state" column="state"/>
<result property="address.zip" column="zip"/>
<result property="address.country" column="country"/>
</resultMap>
<select id="selectStudentWithAddress" parameterType="int"
resultMap="StudentWithAddressResult">
SELECT STUD_ID, NAME, EMAIL, A.ADDR_ID, STREET, CITY, STATE,
ZIP, COUNTRY
FROM STUDENTS S LEFT OUTER JOIN ADDRESSES A ON
S.ADDR_ID=A.ADDR_ID
WHERE STUD_ID=#{studId}
</select>

我们可以在<resultMap>的节点中,嵌套放入Address的信息。在<resultMap>中,学生的地址参数值是通过address.XX来获取的。像这样,我们可以将嵌套对象的属性引用到任何地方。我们可以使用如下的方法来调用嵌套对象:

public interface StudentMapper
{
Student selectStudentWithAddress(int studId);
}
int studId = 1;
StudentMapper studentMapper =
sqlSession.getMapper(StudentMapper.class);
Student student = studentMapper.selectStudentWithAddress(studId);
System.out.println("Student :"+student);
System.out.println("Address :"+student.getAddress());

上面展示了一种方法关于一对一的映射。可是问题来了,如果我们调用的Address对象中也包含了其它的对象,也就是说Address对象与其它对象也存在关系的话,那我们不就要做同样的嵌套工作。

Maybatis提供了更好的方法,那就是应用Nested ResultMap和Nested Select的声明。下面笔者将会介绍。

2. 使用用Nested ResultMap

我们可以获取Student的信息连带着Adress信息,我们可以运用到NestedResultMap,使用方法如下的例子:

<resultMap type="Address" id="AddressResult">
<id property="addrId" column="addr_id"/>
<result property="street" column="street"/>
<result property="city" column="city"/>
<result property="state" column="state"/>
<result property="zip" column="zip"/>
<result property="country" column="country"/>
</resultMap>
<resultMap type="Student" id="StudentWithAddressResult">
<id property="studId" column="stud_id"/>
<result property="name" column="name"/>
<result property="email" column="email"/>
<association property="address" resultMap="AddressResult"/>
</resultMap>
<select id="findStudentWithAddress" parameterType="int"
resultMap="StudentWithAddressResult">
SELECT STUD_ID, NAME, EMAIL, A.ADDR_ID, STREET, CITY, STATE,
ZIP, COUNTRY
FROM STUDENTS S LEFT OUTER JOIN ADDRESSES A ON
S.ADDR_ID=A.ADDR_ID
WHERE STUD_ID=#{studId}
</select>

上面的例子中,<association>元素可能被使用加载一个对象的关联。在例子中,<association>>元素中还涉及到<resultMap>的节点,这个使用与前面的是一样的。我们还可使用如下的方法来使用<association>

<resultMap type="Student" id="StudentWithAddressResult">
<id property="studId" column="stud_id"/>
<result property="name" column="name"/>
<result property="email" column="email"/>
<association property="address" javaType="Address">
<id property="addrId" column="addr_id"/>
<result property="street" column="street"/>
<result property="city" column="city"/>
<result property="state" column="state"/>
<result property="zip" column="zip"/>
<result property="country" column="country"/>
</association>
</resultMap>

3. 使用 Nested Select

我们可以使用嵌套的Select语句来获取Student信息上连带着Adress的信息。

<resultMap type="Address" id="AddressResult">
<id property="addrId" column="addr_id"/>
<result property="street" column="street"/>
<result property="city" column="city"/>
<result property="state" column="state"/>
<result property="zip" column="zip"/>
<result property="country" column="country"/>
</resultMap>
<select id="findAddressById" parameterType="int"
resultMap="AddressResult">
SELECT * FROM ADDRESSES WHERE ADDR_ID=#{id}
</select>
<resultMap type="Student" id="StudentWithAddressResult">
<id property="studId" column="stud_id"/>
<result property="name" column="name"/>
<result property="email" column="email"/>
<association property="address" column="addr_id"
select="findAddressById"/>
</resultMap>
<select id="findStudentWithAddress" parameterType="int"
resultMap="StudentWithAddressResult">
SELECT * FROM STUDENTS WHERE STUD_ID=#{Id}
</select>

   在这个方法中,这个<association>元素的select有名称放到了<select>的id中。所以执行上面的语句将会执行两条SQL语句,一个是findStudentById,另一个是findAddressById,而且后者主要就是加载Addresss的信息。

我们可以用下面的方法来执行findStudentWithAddress.

StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
Student student = mapper.selectStudentWithAddress(studId);
System.out.println(student);
System.out.println(student.getAddress());







你可能感兴趣的:(java,spring,mybatis,web开发)