一对多查询
1. 多表设计
一对一 ,一对一可以设计成一张表结构
一对多
多对一
多对多
2. 搭建开发的环境
以用户(User)和账户(Account)为例,一个用户可以有多个账户。
2.1执行建表语句
sql
CREATE TABLE `user` (
`id` int(11) NOT NULL auto_increment,
`username` varchar(32) NOT NULL COMMENT '用户名称',
`birthday` datetime default NULL COMMENT '生日',
`sex` char(1) default NULL COMMENT '性别',
`address` varchar(256) default NULL COMMENT '地址',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
insert into `user`(`id`,`username`,`birthday`,`sex`,`address`) values (1,'老王','2018-02-27 17:47:08','男','北京'),(2,'熊大','2018-03-02 15:09:37','女','上海'),(3,'熊二','2018-03-04 11:34:34','女','深圳'),(4,'光头强','2018-03-04 12:04:06','男','广州');
CREATE TABLE `account` (
`ID` int(11) NOT NULL 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;
insert into `account`(`ID`,`UID`,`MONEY`) values (1,1,1000),(2,2,1000),(3,2,2000);
2.2编写Account的JavaBean类
java
package com.qcby.domain;
import java.io.Serializable;
/**
* 账号
*/
public class Account implements Serializable{
private Integer id;
private Integer uid;
private Double money;
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;
}
}
2.3编写AccountMapper接口
java
package com.qcby.mapper;
public interface AccountMapper {
}
2.4编写AccountMapper.xml的配置文件
java
<?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.qcby.mapper.AccountMapper">
</mapper>
2.5主配置文件中引入映射配置文件
java
<!--引入映射配置文件-->
<mappers>
<mapper resource="mappers/UserMapper.xml" />
<mapper resource="mappers/AccountMapper.xml" />
</mappers>
3. 多对一查询(一对一查询)
需求:查询账户信息时,同时查询出所属用户的名称和地址。
3.1在Account类中添加user的属性,表示该帐户只属于这个用户
java
package com.qcby.domain;
import java.io.Serializable;
/**
* 账号
*/
public class Account implements Serializable{
private Integer id;
private Integer uid;
private Double money;
// 用户
private 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;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}
3.2在AccountMapper接口中编写查询的方法
java
package com.qcby.mapper;
import com.qcby.domain.Account;
import java.util.List;
public interface AccountMapper {
public List<Account> findAll();
}
3.4编写配置文件
java
<?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.qcby.mapper.AccountMapper">
<!--内连接查询-->
<select id="findAll" resultMap="accountMap">
select a.*,u.username,u.address from account a,user u where a.uid = u.id
</select>
<!--进行数据封装-->
<resultMap id="accountMap" type="com.qcby.domain.Account">
<result property="id" column="id" />
<result property="uid" column="uid"/>
<result property="money" column="money"/>
<association property="user" javaType="com.qcby.domain.User">
<result property="username" column="username"/>
<result property="address" column="address"/>
</association>
</resultMap>
</mapper>
3.5测试方法
java
package com.qcby.test;
import com.qcby.domain.Account;
import com.qcby.mapper.AccountMapper;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
/**
*
*
*
* 测试账号相关
*/
public class Test02 {
/**
* 多对一查询
* @throws IOException
*/
@Test
public void testFindAll() throws IOException {
// 先加载主配置文件,加载到输入流中
InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
// 创建SqlSessionFactory对象,创建SqlSession对象
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream);
// 创建SqlSession对象
SqlSession session = factory.openSession();
// 获取代理对象
AccountMapper mapper = session.getMapper(AccountMapper.class);
// 查询
List<Account> list = mapper.findAll();
// 遍历
for (Account account : list) {
System.out.println(account);
}
// 关闭资源
session.close();
inputStream.close();
}
}
4. 一对多查询
**需求:**如果想查询 select u.*,a.money from user u left join account a on u.id = a.uid 语句的内容
3.1在User类中添加List的属性
java
package com.qcby.domain;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
/**
*
*
*
* 实现类 推荐使用序列化接口 HttpSession序列化
*/
public class User implements Serializable{
// 主键
private Integer id;
// 用户名
private String username;
// 生日
private Date birthday;
// 性别
private String sex;
// 地址
private String address;
// 演示foreach标签
private List<Integer> ids;
// 演示一对多查询
private List<Account> accounts;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public List<Integer> getIds() {
return ids;
}
public void setIds(List<Integer> ids) {
this.ids = ids;
}
public List<Account> getAccounts() {
return accounts;
}
public void setAccounts(List<Account> accounts) {
this.accounts = accounts;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", birthday=" + birthday +
", sex='" + sex + '\'' +
", address='" + address + '\'' +
", ids=" + ids +
", accounts=" + accounts +
'}';
}
}
3.2在UserMapper接口中定义方法
java
public interface UserMapper {
// 查询一对多
public List<User> findOneToMany();
}
3.3编写配置文件
java
<!--一对多查询-->
<select id="findOneToMany" resultMap="userMap">
select u.*,a.money from user u left join account a on u.id = a.uid
</select>
<resultMap type="com.qcby.domain.User" id="userMap">
<result property="id" column="id"/>
<result property="username" column="username"/>
<result property="birthday" column="birthday"/>
<result property="sex" column="sex"/>
<result property="address" column="address"/>
<collection property="accounts" ofType="com.qcby.domain.Account">
<result property="money" column="money"/>
</collection>
</resultMap>
3.5编写测试的方法
java
/**
* 一对多查询
*/
@Test
public void testOneToMany() throws IOException {
// 先加载主配置文件,加载到输入流中
InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
// 创建SqlSessionFactory对象,创建SqlSession对象
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream);
// 创建SqlSession对象
SqlSession session = factory.openSession();
UserMapper mapper = session.getMapper(UserMapper.class);
List<User> list = mapper.findOneToMany();
// 遍历list集合
for (User user : list) {
System.out.println(user);
}
// 关闭资源
session.close();
inputStream.close();
}
5. 多对多查询
可以看成一对多查询,与一对多一样