**
基于XML搭建的Mybatis多表查询
**
前两篇对Mybatis有一个大概的介绍,但是在实际操作中对数据库的查询不可能只查询一张表,往往是对多张表的查询,这一篇继续使用了前面的User表,但是关联了一个账户表。我直接把两张表粘出来这样看的直观一点。
User表:
account表:
为了有一个清晰的结构下面是这个项目所有的文件截图:
对用户的查询
我们定义了一个查询所有用户的方法,查询方式与前面介绍的流程是一样的。但是因为我们现在关联了一张account表(UID是外键),所以我们希望在查询所有用户的时候把用户的账户信息也查询出来。效果图如下:
现在我们来修改代码实现上面的功能。
首先,我们知道一个用户可以有不止一个账户,所以这是一个一对多的查询。我们先在User这个类中加上accounts集合,让查询出来的账户信息封装进去
//一对多关系映射:主表实体应该包含从表实体的集合引用
private List<Account> Accounts;
public List<Account> getAccounts() {
return Accounts;
}
public void setAccounts(List<Account> accounts) {
Accounts = accounts;
}
这个非常的简单,并且UserDao这个接口不用修改,关键是对UserDao.xml这个配置文件的修改。
由于我们查询的时候是多查询一张表的,所以我们肯定要在xml文件中有所体现,这里通过collection标签把两张表关联起来,代码如下(xml文件的一部分):
<resultMap id="userAccountMap" type="user">
<id property="id" column="id"></id>
<result property="username" column="username"></result>
<result property="address" column="address"></result>
<result property="sex" column="sex"></result>
<result property="birthday" column="birthday"></result>
<!-- 配置user对象中accounts集合的映射 -->
<!-- property对应了User类里面的某一个成员变量,ofType是封装的数据类型 -->
<collection property="accounts" ofType="account">
<id column="aid" property="id"></id>
<result column="uid" property="uid"></result>
<result column="money" property="money"></result>
</collection>
</resultMap>
除了这个,我们还要在sql语句上有所体现(这里不是延迟查询,所以sql语句也要改变)
<!-- 查询所有 -->
<select id="findAll" resultMap="userAccountMap">
select * from user u left outer join account a on u.id=a.uid;
</select>
到这里就可以把账户信息查询出来了,我们看一下测试方法:
/**
* 测试查询所有
*/
@Test
public void testFindAll(){
//5.执行查询所有方法
List<User> users = userDao.findAll();
for(User user : users){
System.out.println("---------------每个user的信息---------------");
System.out.println(user);
System.out.println(user.getAccounts());
}
}
查询结果我们在前面已经粘出来了。
对账户的查询
对于账户查询,一个账户只能有一个用户,所以这是一个一对一的查询。
Account类:(由于前两篇没有这一部分,我把全部代码粘出来)
public class Account implements Serializable {
private Integer id;
private Integer uid;
private Double money;
//多对一关系映射:从表实体应该包含一个主表实体的对象引用
private User user;
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Integer getUid() {
return uid;
}
public void setUid(Integer uid) {
this.uid = uid;
}
public Double getMoney() {
return money;
}
public void setMoney(Double money) {
this.money = money;
}
@Override
public String toString() {
return "Account{" +
"id=" + id +
", uid=" + uid +
", money=" + money +
'}';
}
}
AccountDao接口:
public interface AccountDao {
/**
* 查询所有账户
* @return
*/
List<Account> findAll();
/**
* 查询所有账户,并且带有用户名称和地址信息
* @return
*/
List<AccountUser> findAllAccount();
}
AccountDao.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="Gao.Dao.AccountDao">
<!-- 定义封装account与user的resultMap -->
<resultMap id="accountUserMap" type="account">
<id property="id" column="aid"></id>
<result property="uid" column="uid"></result>
<result property="money" column="money"></result>
<!-- 一对一关系映射:配置封装user内容 -->
<association property="user" column="uid">
<id property="id" column="id"></id>
<result column="username" property="username"></result>
<result column="address" property="address"></result>
<result column="sex" property="sex"></result>
<result column="birthday" property="birthday"></result>
</association>
</resultMap>
<!-- 查询所有 -->
<select id="findAll" resultMap="accountUserMap">
<!--select id as userId,username as userName,address as userAddress,sex as userSex,birthday as userBirthday from user;-->
select u.*,a.id as aid,a.uid,a.money from account a,user u where u.id=a.uid;
</select>
<!-- 查询所有账户与用户的地址和用户名 -->
<select id="findAllAccount" resultType="accountUser">
select u.*,a.id as aid,a.uid,a.money from account a,user u where u.id=a.uid;
</select>
</mapper>
这里与刚才UserDao.xml关联另一张表的方式有所不同,这里用了association标签,property对应了User类里面的某一个成员变量,column是account属性中外键的名字。
Test:
/**
* 测试查询所有账户
*/
@Test
public void testFindAll(){
//5.执行查询所有方法
List<Account> accounts = accountDao.findAll();
for(Account account : accounts){
System.out.println("---------------每个account的信息---------------");
System.out.println(account);
System.out.println(account.getUser());
}
}
运行结果:
---------------每个account的信息---------------
Account{id=1, uid=46, money=1000.0}
User{id=46, username='老王', address='北京', sex='男', birthday=Thu Mar 08 07:37:26 CST 2018}
---------------每个account的信息---------------
Account{id=2, uid=45, money=1000.0}
User{id=45, username='update user clear cache', address='山东省', sex='男', birthday=Mon Mar 05 02:04:06 CST 2018}
---------------每个account的信息---------------
Account{id=3, uid=48, money=2000.0}
User{id=48, username='小马宝莉', address='北京修正', sex='女', birthday=Fri Mar 09 01:44:00 CST 2018}