Mybatis中的多表查询
两个表,如下:
- account表:
ID | UID | MONEY |
---|---|---|
1 | 46 | 1000 |
2 | 41 | 1000 |
3 | 46 | 2000 |
- user表:
id | username | birthday | sex | address |
---|---|---|---|---|
41 | 老王 | 2018-02-27 17:47:08 | 男 | 北京 |
42 | 小二王 | 2018-03-02 15:09:37 | 女 | 北京金燕龙 |
43 | 小二王 | 2018-03-04 11:34:34 | 女 | 北京金燕龙 |
46 | 老王 | 2018-03-07 17:37:26 | 男 | 北京 |
48 | 小马宝莉 | 2018-03-08 11:44:00 | 女 | 北京修正 |
- 它们之间 user的id与account的uid外键关联
一对一查询
一个account只能对应一个user
通过account表查询user表的步骤如下:
- 建立account类,并且在account类中应当包含为user的成员变量,如下:
package com.oylong.domain;
import java.io.Serializable;
public class Account implements Serializable {
private Integer id;
private Integer uid;
private Double money;
private User user;
@Override
public String toString() {
return "Account{" +
"id=" + id +
", uid=" + uid +
", money=" + money +
'}';
}
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;
}
}
建立account的dao接口,并且配置映射文件
- dao接口:
package com.oylong.dao; import com.oylong.domain.Account; import java.util.List; public interface AccountDao { public List<Account> findAll (); public List<Account> findAccountUser(); }
- 映射文件:
<?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="com.oylong.dao.AccountDao"> <resultMap id="accountUserMap" type="com.oylong.domain.Account"> <id property="id" column="aid"></id> <result property="uid" column="uid"></result> <result property="money" column="money"></result> <association property="user" column="uid" javaType="com.oylong.domain.User"> <id property="id" column="id"></id> <result property="username" column="username"></result> <result property="birthday" column="birthday"></result> <result property="sex" column="sex"></result> <result property="address" column="address"></result> </association> </resultMap> <select id="findAccountUser" resultMap="accountUserMap"> select u.*,a.id as aid,a.uid,a.money from user u,account a where u.id = a.uid </select> </mapper>
- 运行时通过·accountDao·得到·account·,调用a·ccount·的·getUser·方法即可得到User的内容
- 重点在映射文件和sql语句中。
分析
- 首先我们需要建立表之间的关联关系,如下配置
<resultMap id="accountUserMap" type="com.oylong.domain.Account">
<id property="id" column="aid"></id>
<result property="uid" column="uid"></result>
<result property="money" column="money"></result>
<association property="user" column="uid" javaType="com.oylong.domain.User">
<id property="id" column="id"></id>
<result property="username" column="username"></result>
<result property="birthday" column="birthday"></result>
<result property="sex" column="sex"></result>
<result property="address" column="address"></result>
</association>
</resultMap>
使用resultMap,type为当前需要映射的实体类全限定名,之后按正常写法写完它在自己表中的属性,其中user表为另外一张表,那么我们就需要与之关联。
- 所以
property
为user
,表示需要关联的属性。 column
表示通过什么来关联javaType
表示关联的实体类- 之后补充user表中的字段名
- sql语句
select u.*,a.id as aid,a.uid,a.money from user u,account a where u.id = a.uid
u.*
表示将user
所有的内容都查询a.id as aid
是因为 两表中都有id
,mybatis不知道你要取的是哪个,不处理会异常- 之后通过
where
条件判断
多对一查询
一个user可以拥有多个account
通过user查询account
- 首先在user中添加属性,
List<Account> accounts
public class User implements Serializable {
private Integer id;
private String username;
private Date birthday;
private String sex;
private String address;
private List<Account> accounts;
...
- 之后在dao中,添加相应的接口
public List<User> findAccounts();
- 然后在映射配置文件中,添加
resultMap
配置
<resultMap id="resultmap" type="com.oylong.domain.User">
<id property="id" column="id"></id>
<result property="username" column="username"></result>
<result property="birthday" column="birthday"></result>
<result property="sex" column="sex"></result>
<result property="address" column="address"></result>
<collection property="accounts" ofType="com.oylong.domain.Account">
<id property="id" column="aid"></id>
<result property="uid" column="uid"></result>
<result property="money" column="money"></result>
</collection>
</resultMap>
这里与前面的一对一类似,只是因为返回值是集合,所以改用了collection
标签,ofType
表示集合所对应的类型。
sql语句
<select id="findAccounts" resultMap="resultmap">
select u.*,a.id as aid,a.uid,a.money from user u left outer join account a on a.uid = u.id
</select>
之后即可执行,获得所有用户对应的所有账户
多对多查询
多对多查询,与多对一查询类似,需要一种中间表,两边互相都可查询,主要变化在sql语句上
select u.*,r.id as rid,r.role_name,r.role_desc from user u left outer join user_role ur on u.id=ur.uid left outer join role r on r.id = ur.rid
用了两次左外连接,其他的都与多对一相似