1、1第3章 Mybatis复杂查询框架程序设计(Java)2学习目标mybatismybatis的关联查询的关联查询2mybatismybatis的集合查询的集合查询3mybatis的鉴别器的鉴别器4自定义映射关系自定义映射关系132mybatis的关联查询的关联查询-目录目录o 1)联合查询o 2)构造查询o 3)子查询42.2构造查询构造查询【可选可选】回顾上节课自定义映射关系resultMap的配置:id、result是用来配置实体类(domain.User)中的属性与数据库字段的映射关系的。id、result的本质其实是mybatis根据我们自定义的映射关系使用反射将数据库查询结果中字段
2、的值填充到实体类对应的属性中的 以上是使用id、result的方式定义映射,还有一种方式是使用构造函数的方式来定义映射52.2构造查询构造查询【可选可选】o 首先在domain.User加入构造方法:public class User private String name;private String pass;public User(String name,String pass)this.name=name;this.pass=pass;省略get、set方法62.2构造查询构造查询【可选可选】修改resultMap标签:constructor标签的含义就是使用构造函数来定义映射关系 注
3、意参数的顺序以及为每一个参数指定javaType72.3子查询子查询-任务描述任务描述o 例子3:在例子1的基础上,进行子查询 表名employee(雇员信息表)o username 用户名 字符串 10位 主键o password 密码 字符串 6位 非空o deptid 部门id 整型 外键 表名department(部门信息表)o id 部门id 整型 自动递增 主键o deptname 部门名称 字符串 10位 非空 数据 要求用mybatis框架编程,mysql数据库,查询employee表的所有记录,输出用户名和该用户所在的部门名称82.3子查询子查询-分析子查询过程分析子查询过程
4、o 二阶段查询 阶段1:查询雇员表所有记录o select*from employee 阶段2:从阶段1的查询结果中循环取出每条记录的deptid字段值,查询department表中id=deptid字段值的记录o for(int i=0;i 雇员表的记录数;i+)o int deptid=阶段1中查询结果的下一条记录的deptid字段值;o select*from department where id=deptido 综合阶段1和2的结果就能够得到本例子要求的结果 这种二阶段查询的方式称之为子查询92.3子查询子查询-分析子查询过程分析子查询过程o 上面的分析中涉及两个SQL语句 sele
5、ct*from employee-查询出所有用户 select*from department where id=#deptid-根据部门id获取部门 因此,首先我们在SQL配置文件中加入这两个SQl的配置102.3子查询子查询-分析子查询过程分析子查询过程o select*from employee-查询出所有雇员配置如下:select*from employee112.3子查询子查询-分析子查询过程分析子查询过程o select*from department where id=#deptid-根据部门id获取部门 配置如下:select*from department where id=
6、#deptid 122.3子查询子查询-分析子查询过程分析子查询过程o select*from employee-查询出所有用户配置如下:select*from employee132.3子查询子查询-调试运行及探讨调试运行及探讨o 在app.Test类中执行阶段1查询的代码/3.执行sql语句 List list=sqlSession.selectList(findAllEmployees);o 最后结果与例1没有任何区别o 与例1比较:例1执行一次查询 本例执行n+1次查询(阶段1一次查询,阶段2执行n次,n=阶段1查询的记录数)联合查询的效率高于子查询,因此常用联合查询的映射方式143集
7、合查询集合查询-任务描述任务描述o 例子4:集合查询 表名employee(雇员信息表)o username 用户名 字符串 10位 主键o password 密码 字符串 6位 非空o deptid 部门id 整型 外键 表名department(部门信息表)o id 部门id 整型 自动递增 主键o deptname 部门名称 字符串 10位 非空 数据 要求用mybatis框架编程,mysql数据库,查询employee表的所有记录,输出用户名和该用户所在的部门名称153集合查询集合查询-分析分析o 一个雇员属于一个部门o 一个部门包含多个雇员o 联合查询的时候,我们站在雇员的角度,Em
8、ployee中包含一个Departmento 现在我们站在部门的角度,一个Department包含多个Employeeo 因此,实体类代码结构修改如下:163集合查询集合查询-分析分析o domain.Employee实体类:public class Employee private String name;private String pass;private int deptid;省略get,set方法 173集合查询集合查询-分析分析o domain.Department实体类:public class Departmentprivate int id;private String na
9、me;private List employees;/多个雇员(是个集合)省略get,set方法 183集合查询集合查询-步骤步骤1o 在里修改查询结果类型映射resultMap标签配置说明:collection 标签是用来配置集合的collection property=“employees“对应于java实体类中employees属性,显而易见,它是arraylist集合类型javaType=”ArrayList”,里边的类型必定是User,则ofType=domain.User“193集合查询集合查询-步骤步骤2o 修改SQL配置中的resultMap属性值 select*fromemp
10、loyee,departmentwhere employee.deptid=department.id 203集合查询集合查询-调试运行及探讨调试运行及探讨o 在app.Test类中执行如下代码/3.执行sql语句 List list=sqlSession.selectList(findDepts);/4.输出结果 for(Department dept:list)List employees=dept.getEmployees();for(Employee item:employees)System.out.println(item.getName()+:+dept.getName();o 最后结果与例1没有任何区别212集合查询集合查询-练习练习o 查询学生信息表student所有记录 表名student(学生信息表)o no 学号 字符串 10位 主键o name 姓名 字符串 8位 非空o classno 班级编号 字符串 10位 外键 表名class(班级信息表)o no 班级编号 字符串 10位 主键o name 名称 字符串 10位 非空o 要求用mybatis框架编程,mysql数据库,查询user表的所有记录,输出学生姓名和该生所在的班级名称,使用这节课讲的集合查询的方式