1.1.1. 一对多关联
一个Person可以拥有一个或多个Address,而每个Address对应于唯一一个Person,因此Person和Address之间存在一对多的关系。本文介绍使用MyBatis如何进行基于List的一对多映射。
Person类:
/** * @Title: Person.java * @Package com.test.mybatis3.pojo * @Description: * @author http://www.cnblogs.com/coe2coe/ * @date 2017年4月9日 下午3:21:32 * @version V1.0 */ package com.test.mybatis3.pojo; import java.util.List; /** * @ClassName: Person * @Description: * @author http://www.cnblogs.com/coe2coe/ * @date 2017年4月9日 下午3:21:32 * */ public class Person { private String id; private String name; private int status; //用于满足POJO要求的无参数构造函数。 public Person() { } public String getId() { return id; } public String getName() { return name; } public int getStatus() { return status; } public void setId(String id) { this.id = id; } public void setName(String name) { this.name = name; } public void setStatus(int status) { this.status = status; } @Override public String toString() { return "Person [id=" + id + ", name=" + name + ", status=" + status +"]"; } private List<Address> addressList; public List<Address> getAddressList() { return addressList; } public void setAddressList(List<Address> addressList) { this.addressList = addressList; } }
Address类:
/** * @Title: Address.java * @Package com.test.mybatis3.pojo * @Description: * @author http://www.cnblogs.com/coe2coe/ * @date 2017年4月17日 下午10:56:26 * @version V1.0 */ package com.test.mybatis3.pojo; /** * @ClassName: Address * @Description: * @author http://www.cnblogs.com/coe2coe/ * @date 2017年4月17日 下午10:56:26 * */ public class Address { private int addressid; private String personid; private String addressname; public int getAddressid() { return addressid; } public void setAddressid(int addressid) { this.addressid = addressid; } public String getPersonid() { return personid; } public void setPersonid(String personid) { this.personid = personid; } public String getAddressname() { return addressname; } public void setAddressname(String addressname) { this.addressname = addressname; } @Override public String toString() { return "Address [addressid=" + addressid + ", personid=" + personid + ", addressname=" + addressname + "]"; } private Person person; public Person getPerson() { return person; } public void setPerson(Person person) { this.person = person; } }
Mapper配置文件:
有两种映射方式:
(1)一种是使用一条JOIN语句将Person和对应的Address集合全部查询出来。
(2)另外一种是先查询出Person列表,再根据personid使用SELECT子查询查询出Address集合。
使用JOIN语句的Mapper配置方式:
<!-- 查询Person和对应的Address集合 --> <select id="findPersonAndAddress" resultMap="personResultMap" > select a.* ,b.* from t_person a left outer join t_address b on (a.id = b.personid) order by a.id asc , b.addressid asc </select> <!-- 将t_person映射到Person类 --> <resultMap type="com.test.mybatis3.pojo.Person" id="personResultMap"> <id property="id" column="id" /> <result property="name" column="name" /> <result property="status" column="status" /> <!-- 将该Person对应的t_address记录集映射到addressList属性 --> <collection property="addressList" javaType="java.util.ArrayList" resultMap="addressResultMap" /> </resultMap> <!-- 将t_address记录映射到Address类 --> <resultMap type="com.test.mybatis3.pojo.Address" id="addressResultMap"> <id property="addressid" column="addressid" /> <result property="personid" column="personid" /> <result property="addressname" column="addressname" /> </resultMap>
使用嵌套查询的配置方式:
<!-- 查询Person和对应的Address集合 --> <!-- 计划采用select子查询的方式来获取Address集合,因此此处仅查询person --> <select id="findPersonAndAddress" resultMap="personResultMap" > select * from t_person order by id asc </select> <!-- 将t_person映射到Person类 --> <resultMap type="com.test.mybatis3.pojo.Person" id="personResultMap"> <id property="id" column="id" /> <result property="name" column="name" /> <result property="status" column="status" /> <!-- 将该Person对应的t_address记录集映射到addressList属性 --> <!-- select:一个子查询的id --> <collection select="findAddressByPersonid" column="id" property="addressList" javaType="java.util.ArrayList" /> </resultMap> <!-- 将t_address记录映射到Address类 --> <resultMap type="com.test.mybatis3.pojo.Address" id="addressResultMap"> <id property="addressid" column="addressid" /> <result property="personid" column="personid" /> <result property="addressname" column="addressname" /> </resultMap> <!-- 根据personid查询Address集合 --> <select parameterType="string" resultMap="addressResultMap" id="findAddressByPersonid" > select * from t_address where personid=#{id} </select>
Mapper接口的方法:
public interface PersonMapper { List<Person> findPersonAndAddress() throws Exception; }
单元测试代码如下:
//打开Session。 session = sessionBuilder.openSession(); //找到MyBatis自动实现的PersonMapper接口的代理对象。 PersonMapper personMapper = session.getMapper(PersonMapper.class); //查询Person和相应的Address集合。 List<Person> persons = personMapper.findPersonAndAddress(); for(Person person : persons){ System.out.println(person); for(Address address: person.getAddressList()){ System.out.println(address); } System.out.println("----------------------"); }
运行结果如下:
0 [main] DEBUG com.test.mybatis3.mapper.PersonMapper.findPersonAndAddress - ==> Preparing: select a.* ,b.* from t_person a left outer join t_address b on (a.id = b.personid) order by a.id asc , b.addressid asc
42 [main] DEBUG com.test.mybatis3.mapper.PersonMapper.findPersonAndAddress - ==> Parameters:
68 [main] TRACE com.test.mybatis3.mapper.PersonMapper.findPersonAndAddress - <== Columns: id, name, status, addressid, personid, addressname
68 [main] TRACE com.test.mybatis3.mapper.PersonMapper.findPersonAndAddress - <== Row: lisi, li si, 0, 4, lisi, road1
72 [main] TRACE com.test.mybatis3.mapper.PersonMapper.findPersonAndAddress - <== Row: lisi, li si, 0, 5, lisi, road2
74 [main] TRACE com.test.mybatis3.mapper.PersonMapper.findPersonAndAddress - <== Row: lisi, li si, 0, 6, lisi, road3
74 [main] TRACE com.test.mybatis3.mapper.PersonMapper.findPersonAndAddress - <== Row: zhangsan, zhang san, 0, 1, zhangsan, street1
76 [main] TRACE com.test.mybatis3.mapper.PersonMapper.findPersonAndAddress - <== Row: zhangsan, zhang san, 0, 2, zhangsan, street2
76 [main] TRACE com.test.mybatis3.mapper.PersonMapper.findPersonAndAddress - <== Row: zhangsan, zhang san, 0, 3, zhangsan, street3
76 [main] DEBUG com.test.mybatis3.mapper.PersonMapper.findPersonAndAddress - <== Total: 6
Person [id=lisi, name=li si, status=0]
Address [addressid=4, personid=lisi, addressname=road1]
Address [addressid=5, personid=lisi, addressname=road2]
Address [addressid=6, personid=lisi, addressname=road3]
----------------------
Person [id=zhangsan, name=zhang san, status=0]
Address [addressid=1, personid=zhangsan, addressname=street1]
Address [addressid=2, personid=zhangsan, addressname=street2]
Address [addressid=3, personid=zhangsan, addressname=street3]
----------------------