【Mybatis】MyBatis之表的关联查询(五)
本章介绍Mybatis之表的关联查询
一对一关联
查询员工信息以及员工的部门信息
1、准备表employee员工表,department部门表
CREATE TABLE `employee` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`last_name` varchar(255) DEFAULT NULL,
`gender` char(1) DEFAULT NULL,
`email` varchar(255) DEFAULT NULL,
`dept_id` int(11) DEFAULT NULL COMMENT '部门ID',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `department` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`dep_name` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
2、新建员工实体类(EmployeePlus.java),以及部门实体类(Department.java)
package com.hd.test.pojo; public class EmployeePlus { private Integer id;
private String lastName;
private String gender;
private String email; private Department dept; public EmployeePlus() {
// TODO Auto-generated constructor stub
} public EmployeePlus(String lastName, String gender, String email) {
super();
this.lastName = lastName;
this.gender = gender;
this.email = email;
} public EmployeePlus(Integer id, String lastName, String gender, String email) {
super();
this.id = id;
this.lastName = lastName;
this.gender = gender;
this.email = email;
} public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
} public Department getDept() {
return dept;
} public void setDept(Department dept) {
this.dept = dept;
} @Override
public String toString() {
return "EmployeePlus [id=" + id + ", lastName=" + lastName + ", gender=" + gender + ", email=" + email
+ ", dept=" + dept + "]";
} }
package com.hd.test.pojo; public class Department { private Integer id;
private String deptName; public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getDeptName() {
return deptName;
}
public void setDeptName(String deptName) {
this.deptName = deptName;
} @Override
public String toString() {
return "Department [id=" + id + ", deptName=" + deptName + "]";
} }
3、编辑sql映射文件EmployeeMapperPlus.xml,文件中有2种resultMap,都可以使用
<?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.hd.test.mapper.EmployeeMapperPlus"> <!-- 联合查询:级联属性封装结果集 -->
<!-- 封装方式1:普通封装 -->
<resultMap type="com.hd.test.pojo.EmployeePlus" id="MyEmployeeDept">
<id column="id" property="id"/>
<result column="last_name" property="lastName"/>
<result column="gender" property="gender"/>
<result column="did" property="dept.id"/>
<result column="dept_name" property="dept.deptName"/>
</resultMap> <!-- 封装方式2:采用association标签的方式封装 -->
<resultMap type="com.hd.test.pojo.EmployeePlus" id="MyEmployeeDept2">
<id column="id" property="id"/>
<result column="last_name" property="lastName"/>
<result column="gender" property="gender"/> <association property="dept" javaType="com.hd.test.pojo.Department">
<id column="did" property="id"/>
<result column="dept_name" property="deptName"/>
</association>
</resultMap> <select id="getMyEmployeeDept" resultMap="MyEmployeeDept" > <!-- resultMap="MyEmployeeDept2" -->
SELECT
emp.id,
emp.last_name,
emp.gender,
dept.id AS did,
dept.dep_name AS dept_name
FROM
employee emp
LEFT JOIN department dept ON emp.dept_id = dept.id
WHERE
emp.id = #{id}
</select> </mapper>
4、在mybatis-config.xml文件中注册EmployeeMapperPlus.xml
<mappers>
<!-- 添加sql射文件到Mybatis的全局配置文件中 -->
<mapper resource="mapper/EmployeeMapperPlus.xml" />
</mappers>
5、编写接口(DepartmentPlusMapper.java)
package com.hd.test.mapper; import com.hd.test.pojo.DepartmentPlus; public interface DepartmentPlusMapper { public DepartmentPlus getDeparmentAndEmp(Integer id); }
6、测试类
@Test
public void test01() throws IOException { InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); SqlSession session = sqlSessionFactory.openSession(); try {
EmployeeMapperPlus mapper = session.getMapper(EmployeeMapperPlus.class);
EmployeePlus employeePlus = mapper.getMyEmployeeDept(1);
System.out.println(employeePlus); } catch (Exception e) {
e.printStackTrace();
}finally {
session.close();
} }
7、执行结果,可以看到员工和部门信息同时查出来了,如下:
一对一关联查询拓展
a、分步的形式查询,即先查员工信息,然后查部门执行,需要执行2次sql
1)编辑EmployeeMapperPlus.xml文件,新增内容
<resultMap type="com.hd.test.pojo.EmployeePlus" id="MyEmployeeByStep">
<id column="id" property="id"/>
<result column="last_name" property="lastName"/>
<result column="gender" property="gender"/> <association property="dept" select="com.hd.test.mapper.DepartmentMapper.getDeparmentById" column="dept_id"> </association>
</resultMap> <select id="getMyEmployeeByStep" resultMap="MyEmployeeByStep" >
SELECT id, last_name, gender, dept_id FROM employee WHERE id = #{id}
</select>
2)新增一个 DepartmentMapper.xml 文件,并且也在mybatis-config.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="com.hd.test.mapper.DepartmentMapper">
<select id="getDeparmentById" resultType="com.hd.test.pojo.Department">
select id, dep_name deptName from department where id =
#{id}
</select>
</mapper>
3、调用方法如下:
@Test
public void test02() throws IOException { InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); SqlSession session = sqlSessionFactory.openSession(); try {
EmployeeMapperPlus mapper = session.getMapper(EmployeeMapperPlus.class);
EmployeePlus employeePlus = mapper.getMyEmployeeByStep(1);
System.out.println(employeePlus.getLastName());
System.out.println(employeePlus.getDept());
} catch (Exception e) {
e.printStackTrace();
}finally {
session.close();
} }
4、执行结果如下,可以从日志中看到,先执行sql查询了员工信息表的数据,然后在执行sql查询了部门表的数据,分两次查询
b、分步的形式懒加载查询,即先查员工信息,然后在需要使用部门信息的时候,在去查询部门信息
方法1:在上面分步的形式查询基础上,在mybatis-config.xml文件中设置全局变量,然后执行
<settings>
<!-- 延迟加载的全局开关。当开启时,所有关联对象都会延迟加载。 特定关联关系中可通过设置fetchType属性来覆盖该项的开关状态。 -->
<setting name="lazyloadingenabled" value="true"/>
<!-- 当开启时,任何方法的调用都会加载该对象的所有属性。否则,每个属性会按需加载 -->
<setting name="aggressivelazyloading" value="false"/>
</settings>
方法2:在上面分步的形式查询基础上,在sql配置文件中,配置resultMap中association标签的 fetchType 属性,fetchType 属性有2个值:lazy(懒加载),eager(立即加载),然后执行
<resultMap type="com.hd.test.pojo.EmployeePlus" id="MyEmployeeByStep">
<id column="id" property="id"/>
<result column="last_name" property="lastName"/>
<result column="gender" property="gender"/> <association property="dept" select="com.hd.test.mapper.DepartmentMapper.getDeparmentById" column="dept_id" fetchType="lazy">
</association>
</resultMap>
优先级:association标签的 fetchType 属性设置的优先级高于mybatis-config.xml文件中的e设置
一对多关联
查询部门信息,以及部门下所有员工信息
1、表结构上,2张表,员工和部门
2、新建部门实体类(DepartmentPlus.java),以及员工实体类(Employee.java)
package com.hd.test.pojo; import java.util.List; public class DepartmentPlus { private Integer id;
private String deptName; private List<Employee> emps; public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getDeptName() {
return deptName;
}
public void setDeptName(String deptName) {
this.deptName = deptName;
}
@Override
public String toString() {
return "DepartmentPlus [id=" + id + ", deptName=" + deptName + ", emps=" + emps + "]";
}
public List<Employee> getEmps() {
return emps;
}
public void setEmps(List<Employee> emps) {
this.emps = emps;
} }
package com.hd.test.pojo; public class Employee { private Integer id;
private String lastName;
private String gender;
private String email; public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
@Override
public String toString() {
return "Employee [id=" + id + ", lastName=" + lastName + ", gender=" + gender + ", email=" + email + "]";
} }
3、编辑sql映射文件DepartmentPlusMapper.xml,文件中有2种查询方式,一种一次性查处所有数据,另一种分步查询数据
<?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.hd.test.mapper.DepartmentPlusMapper"> <!--嵌套结果集的方式,使用collection标签定义关联的集合类型的属性封装规则 -->
<resultMap type="com.hd.test.pojo.DepartmentPlus" id="DeparmentAndEmpMap">
<id column="id" property="id"/>
<id column="dep_name" property="deptName"/>
<!--
collection定义关联集合类型的属性的封装规则
ofType:指定集合里面元素的类型
-->
<collection property="emps" ofType="com.hd.test.pojo.Employee">
<!-- 定义这个集合中元素的封装规则 -->
<id column="eid" property="id"/>
<result column="last_name" property="lastName"/>
<result column="email" property="email"/>
<result column="gender" property="gender"/>
</collection>
</resultMap> <select id="getDeparmentAndEmp" resultMap="DeparmentAndEmpMap">
SELECT
dept.id,
dept.dep_name,
emp.id AS eid,
emp.last_name,
emp.gender
FROM
department dept
LEFT JOIN employee emp ON dept.id = emp.dept_id
WHERE dept.id = #{id}
</select> <!-- 分步查询方式 -->
<resultMap type="com.hd.test.pojo.DepartmentPlus" id="DeparmentAndEmpMapByStep">
<id column="id" property="id"/>
<id column="dep_name" property="deptName"/>
<collection property="emps" select="com.hd.test.mapper.EmployeeMapper.getEmployeeByDeptId" column="id" fetchType="eager">
</collection>
</resultMap> <!--
resultMap-collection 扩展:多列的值传递过去, 将多列的值封装map传递;
column="{key1=column1,key2=column2}" 如下也是可行的
<collection property="emps" select="com.hd.test.mapper.EmployeeMapper.getEmployeeByDeptId" column="{deptId=id}" fetchType="eager">
</collection>
--> <select id="getDeparmentAndEmpMapByStep" resultMap="DeparmentAndEmpMapByStep">
SELECT id, dep_name FROM department WHERE id = #{id}
</select> </mapper>
4、编辑EmployeeMapper.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="com.hd.test.mapper.EmployeeMapper">
<select id="getEmployeeByDeptId" resultType="com.hd.test.pojo.Employee">
select id, last_name lastName, gender, email from employee where dept_id = #{deptId}
</select>
</mapper>
5、在mybatis-config.xml文件中注册DepartmentPlusMapper.xml 和 EmployeeMapper.xml文件
6、编写接口(DepartmentPlusMapper.java)
package com.hd.test.mapper; import com.hd.test.pojo.DepartmentPlus; public interface DepartmentPlusMapper { public DepartmentPlus getDeparmentAndEmp(Integer id); public DepartmentPlus getDeparmentAndEmpMapByStep(Integer id); }
7、测试类
@Test
public void test03() throws IOException { InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); SqlSession session = sqlSessionFactory.openSession(); try {
DepartmentPlusMapper mapper = session.getMapper(DepartmentPlusMapper.class);
DepartmentPlus departmentPlus = mapper.getDeparmentAndEmp(1);
System.out.println(departmentPlus);
// System.out.println(employeePlus.getDept());
} catch (Exception e) {
e.printStackTrace();
}finally {
session.close();
} } @Test
public void test04() throws IOException { InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); SqlSession session = sqlSessionFactory.openSession(); try {
DepartmentPlusMapper mapper = session.getMapper(DepartmentPlusMapper.class);
DepartmentPlus departmentPlus = mapper.getDeparmentAndEmpMapByStep(1);
System.out.println(departmentPlus.getDeptName());
System.out.println(departmentPlus.getEmps());
} catch (Exception e) {
e.printStackTrace();
}finally {
session.close();
} }
8、执行结果,可以看到部门信息以及部门下所有员工信息同时查出来了,如下:
a、一次性查询方法:getDeparmentAndEmp(),结果:
b、分步查询方法:getDeparmentAndEmpMapByStep(),结果:
【Mybatis】MyBatis之表的关联查询(五)的更多相关文章
- mybatis一对多关系的关联查询
问题描述:实现两张表的关联查询 学生表: 班级表: 要实现学生管理信息中有所在班级的名称,即如下图所示 1.对应学生表的pojo类写全班级表中的字段(适用于要连接的表字段较少的情况) sql语句直接在 ...
- Mybatis学习总结四(关联查询)
一.一对一查询 实例:查询所有订单信息,关联查询下单用户信息. Method1:使用resultType,定义订单信息po类,此po类中包括了订单信息和用户信息. public class Order ...
- 多张表进行关联查询---->删除某个数据的时候出现还有子记录的提示
多张表进行关联查询的时候,当某张表里面的一个字段在另外一张表有定义,就相当于一张表是另外一张表的子表:比如现在开发所遇到的一个问题: 这个是在删除sys_user表的里面的数据的时候出现的问题,因为s ...
- Mongoose 多表(N个表)关联查询aggregate
Mongoose 多表(N个表)关联查询概述 需求:文章(article),文章分类(articlecate),用户(user)这三个表之间的关系,一篇文章对应文章分类表中的某个类型,对应着用户表中的 ...
- Mybatis框架学习总结-表的关联查询
一对一关联 创建表和数据:创建一张教师表和班级表,这里假设一个老师只负责教一个班,那么老师和班级之间的关系就是一种一对一的关系. CREATE TABLE teacher( t_id INT PRIM ...
- mybatis 使用接口增删改查和两表一对一关联查询
导包 总配置文件 <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE configuration ...
- Mybatis中多表联查,查询出来的字段出现重名,造成数据异常的解决方法!
在做一对多出现的问题,引发的思考:当数据库表中,主表的主键id和明细表的中的字段名相同时怎么办?Mybatis进行自动映射赋值的时候会不会出现异常? 注意:M ...
- Mybatis框架基础入门(七)--关联查询
1.一对一查询 1.1 使用resultType接收查询结果 修改pojo类 public class OrderUser extends order { private String usernam ...
- MyBatis 一对多,多对一关联查询的时候Mapper的顺序
要先写association,然后写collection:这是由DTD决定的: <resultMap ...> <association ...> </associati ...
随机推荐
- Python学习随笔(1)--可视化工具plotly使用
把数据库某列数据取出来,然后再在本地生成html文件形成可视化视图显示 #!/usr/bin/python# coding=utf-8 import pymysqlimport plotly.plot ...
- urllib、urllib2、urllib3区别和使用
python3中把urllib和urllib合并为一个库了,urllib对应urllib.request 1.) python 中最早内置拥有的网络请求模块就是 urllib,我们可以看一下 urll ...
- 基于Ubuntu系统XAMPP环境安装以及DVWA渗透测试系统安装(详解的不能再详解了)
首先这是X勺年人生第二次博,用来记录一下转折于我而言.做个简介,这个Ubuntu是linux的一种吧,然 然后这个Ubuntu是我刚简单安装(在虚拟机上)没有经过任何配置,从头开始,我这绝壁的小白,其 ...
- JavaScript Array some() 方法
some 判断数组中是否至少有一个元素满足条件 只要有一个满足就返回true 只有都不满足时才返回false 语法: array.some(function(value,index,array),th ...
- fiddler抓https包
若手机端安装证书后还是无法抓取到https请求,请注意手机端证书开关是否开启: eg:ios 设置---通用---关于本机---证书信任设置:开启证书信任 若还是无法抓包,则可以进行一下操作: 给fi ...
- Functional Language
1.What is functional language? 函数式语言(functional language)一类程序设计语言,是一种非冯·诺伊曼式的程序设计语言.函数式语言主要成分是原始函数.定 ...
- Rust2018
Rust已经有2本中文书了 <<深入浅出Rust>> <<Rust编程之道>> 带着aync的rust 2019会更精彩 看async , 在这里htt ...
- Python设计模式 - UML - 状态图(State Machine Diagram)
简介 状态图主要用于描述对象在其生命周期中各种状态.状态之间的转换过程.触发状态转换的各种事件(条件)及执行的动作. 状态图构建步骤 - 找出适合用状态图描述的类.确定类中需要做状态图的重要对象 - ...
- ES6学习笔记(let,const,变量的解构赋值)
1.let: ; i < 3; i++) { let i = 'abc'; console.log(i); } // abc // abc // abc 不存在变量提升,它所声明的变量一定要在声 ...
- Windows防火墙开启ping,禁ping的配置
当我通过本机Ping另一台在同一局域网内(即在同一网段)的计算机时,发现,如果防火墙开启的话,无论如何也ping不通.一旦关闭防火墙就可以ping通了.这是为什么呢?究竟该怎么设置呢? 原因是这样的, ...