MyBatis实现一对多,多对一,多对多查询
1. 多表设计
- 一对多
- 多对一
- 多对多
2. 搭建开发的环境
1.执行建表语句
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.编写Account的JavaBean类
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;}
}
3.编写AccountMapper接口
public interface AccountMapper {}
4.编写AccountMapper.xml的配置文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.qcbyjy.mapper.AccountMapper">
</mapper>
5.主配置文件中引入映射配置文件
<!--引入映射配置文件-->
<mappers><mapper resource="mappers/UserMapper.xml" /><mapper resource="mappers/AccountMapper.xml" />
</mappers>
3. 一对多查询(一个人对应多个账户)
如果想查询 select u.*,a.money from user u left join account a on u.id = a.uid 语句的内容
在User类中添加List的属性
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;}
@Overridepublic String toString() {return "User{" +"id=" + id +", username='" + username + '\'' +", birthday=" + birthday +", sex='" + sex + '\'' +", address='" + address + '\'' +", ids=" + ids +", accounts=" + accounts +'}';}
}
3.在UserMapper接口中定义方法
// 查询一对多public List<User> findOneToMany();
4.编写配置文件
<!--一对多查询--><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.qcbyjy.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.qcbyjy.domain.Account"><result property="money" column="money"/></collection></resultMap>
5.编写测试的方法
/*** 一对多查询*/@Testpublic 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();}
6.结果:
4. 多对一查询(多个账户对应一个人)
需求:查询的数据中包含account所有的字段,再包含用户的名称和地址
在Account类中添加user的属性,表示该帐户只属于这个用户
import java.io.Serializable;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;}@Overridepublic String toString() {return "Account{" +"id=" + id +", uid=" + uid +", money=" + money +", user=" + user +'}';}
}
3.在AccountMapper接口中编写查询的方法
import com.qcby.entity.Account;import java.util.List;public interface AccountMapper {public List<Account> findAll();
}
4. 编写配置文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.qcbyjy.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.qcbyjy.domain.Account"><result property="id" column="id" /><result property="uid" column="uid"/><result property="money" column="money"/><association property="user" javaType="com.qcbyjy.domain.User"><result property="username" column="username"/><result property="address" column="address"/></association></resultMap>
</mapper>
5.测试方法
import cn.tx.domain.Account;
import cn.tx.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*/@Testpublic 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();}
}
6.结果:
5. 多对多查询
1.执行SQL语句,创建表结构
CREATE TABLE `role` (`ID` int(11) NOT NULL COMMENT '编号',`ROLE_NAME` varchar(30) default NULL COMMENT '角色名称',`ROLE_DESC` varchar(60) default NULL COMMENT '角色描述',PRIMARY KEY (`ID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
insert into `role`(`ID`,`ROLE_NAME`,`ROLE_DESC`) values (1,'组长','管理整个组'),(2,'班主任','管理整个班级'),(3,'校长','管理整个学校');
CREATE TABLE `user_role` (`UID` int(11) NOT NULL COMMENT '用户编号',`RID` int(11) NOT NULL COMMENT '角色编号',PRIMARY KEY (`UID`,`RID`),KEY `FK_Reference_10` (`RID`),CONSTRAINT `FK_Reference_10` FOREIGN KEY (`RID`) REFERENCES `role` (`ID`),CONSTRAINT `FK_Reference_9` FOREIGN KEY (`UID`) REFERENCES `user` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
insert into `user_role`(`UID`,`RID`) values (1,1),(1,2),(2,2);
2.编写Role实体类
import java.io.Serializable;
/*** 角色模块*/
public class Role implements Serializable{
private static final long serialVersionUID = 4836306672907553166L;private Integer id;private String role_name;private String role_desc;public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getRole_name() {return role_name;}public void setRole_name(String role_name) {this.role_name = role_name;}public String getRole_desc() {return role_desc;}public void setRole_desc(String role_desc) {this.role_desc = role_desc;}
}
3.编写接口
import com.qcby.entity.Role;import java.util.List;public interface RoleMapper {public List<Role> findAll();
}
4.编写配置文件
<select id="findAll" resultMap="roleMap">SELECT r.*,u.username FROM USER u,user_role ur,role r WHERE u.id = ur.UID AND ur.RID = r.ID</select><resultMap type="role" id="roleMap"><id property="id" column="id"/><result property="role_name" column="role_name"/><result property="role_desc" column="role_desc"/><collection property="users" ofType="user"><result property="username" column="username"/> </collection></resultMap>
5.编写测试方法
import com.qcby.entity.Role;
import com.qcby.mapper.AccountMapper;
import com.qcby.mapper.RoleMapper;
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.After;
import org.junit.Before;
import org.junit.Test;import java.io.IOException;
import java.io.InputStream;
import java.util.List;public class RoleTest {private InputStream in;private SqlSession session;private RoleMapper mapper;@Beforepublic void init() throws Exception {// 加载配置文件in = Resources.getResourceAsStream("SqlMap.xml");// 创建工厂对象SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);// 创建Session对象session = factory.openSession();// 获取到代理对象mapper = session.getMapper(RoleMapper.class);System.out.println("执行开始");}@Afterpublic void destory() throws IOException {in.close();session.close();System.out.println("执行结束");}@Testpublic void findAll(){List<Role> roles = mapper.findAll();for (Role role : roles) {System.out.println(role);}}
}
6.测试结果:
感谢大家观看