MyBatis多表之一对多关联查询
一对多关联查询是指在查询一方
对象的同时把与它关联的多方
对象也查询出来,这里以用户(User)
和账户(Account)
为例,一个用户可以有多个账户,一个账户只能属于一个用户,用户和账户是一对多关系。
建议在开始之前,新建一个maven项目,将上一个工程的内容复制到新工程内,这样便于修改使用。
新建account
数据库表,语句如下:
注意: 这里的uid是外键,关联user
表,表中的数据大家可以根据自己的user
表中的数据自行插入。
CREATE TABLE `account` (
`ID` int(11) NOT NULL auto_increment COMMENT '编号',
`UID` int(11) default NULL COMMENT '用户编号',
`MONEY` double default NULL COMMENT '金额',
PRIMARY KEY (`ID`),
KEY `FK_Reference_8` (`UID`),
CONSTRAINT `FK_Reference_8` FOREIGN KEY (`UID`) REFERENCES `user` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
创建Account类如下:
package com.zfnotes.beans;
public class Account {
private Integer id;
private Integer uid;
private double money;
// 省略getter和setter方法
}
修改我们的User
类,因为是一对多关系映射,所以主表实体应该包含从表实体的集合引用,因此添加List<Account> accounts
属性,,不要忘记添加getter和setter方法:
package com.zfnotes.beans;
import java.util.Date;
import java.util.List;
public class User {
private Integer id;
private String username;
private Date birthday;
private String sex;
private String address;
private List<Account> accounts;
// 省略getter和setter方法
}
将UserDao接口的映射配置文件中id="findAll"
的select标签
的内容修改如下,这样就可以在查询user表中的数据的同时将account表中与之关联的数据查询出来并且封装到对应User类对象的accounts属性
中:
<!--定义User的resultMap-->
<resultMap id="userAccountMap" type="user">
<id property="id" column="id"/>
<result column="username" property="username"/>
<result column="address" property="address"/>
<result column="sex" property="sex"/>
<result column="birthday" property="birthday"/>
<!--配置User对象中accounts集合的映射
ofType指定集合中元素的类型,这里使用别名-->
<collection property="accounts" ofType="account">
<id property="id" column="aid"/>
<result property="uid" column="uid"/>
<result property="money" column="money"/>
</collection>
</resultMap>
<!--配置查询所有User, id为namespace限定的接口中的方法名-->
<select id="findAll" resultMap="userAccountMap">
select u.*, a.id as aid, a.uid, a.money from user u left outer join account a on a.uid=u.id;
</select>
详解:
- resultMap标签:
- id属性:唯一标识,供select标签引用。
- type属性:指定要映射的实体类,使用完全限定类名或者别名。
- id标签:配置主键属性。
- result标签:配置非主键属性。
- property属性:指定实体类属性名。
- column属性:指定数据库表字段名。
- collection标签:用于建立一对多中集合属性的对应关系。
- property属性:指定集合属性的属性名。
- ofType属性:指定集合中元素的类型,这里使用别名,大家可以自行配置别名。
注意: 在collection标签
中的id标签
的column属性
的值并不是id而是aid, 这是因为我们的user
表和account
表中都有id
字段,为了防止混淆,我们在写查询语句时给account
表中的id
字段起了别名aid
。
继续使用持久层接口(UserDao)中的findAll
方法,不做改变。
修改测试类中testFindAll
测试方法如下,运行该测试方法即可看到效果,为了更明显的看到效果,请重写Account类中的toString()
方法:
/**
* 一对多查询
*/
@Test
public void testFindAll() {
List<User> users = userDao.findAll();
for (User user : users) {
System.out.println(user);
System.out.println(user.getAccounts());
System.out.println("------------");
}
}