在我们domain的包中,每一个student都关联了一个地址。STUDENT的表中拥有ADDR_ID的列这个是作为ADDRESS表的外主键。
STUDENT表的信息如下:
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的声明。下面笔者将会介绍。
我们可以获取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>
我们可以使用嵌套的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());