MyBatis(八):高级结果映射
本文是按照狂神说的教学视频学习的笔记,强力推荐,教学深入浅出一遍就懂!b站搜索狂神说或点击下面链接
https://space.bilibili.com/95256449?spm_id_from=333.788.b_765f7570696e666f.2
联表查询
环境准备
两个很简单的表,学生表记录了老师的pk

零、简单的联表查询
以下两个实体类,学生表记录了老师的pk---->Teacher的id是Student的tid。
//省略了无参、有参构造、get、set、重写toString
public class Student {
private int id;
private String name;
private int tid;
}
public class Teacher {
private int id;
private String name;
}
1.假如需求是查出每个学生的信息和对应老师的名字,那么sql语句应该是
select s.*,t,name from student s,teacher t where s.tid = t.id
2.直接把结果放在map里面就可以了
Mapper.xml
<mapper namespace="com.rzp.dao.StudentMapper">
<select id="getByTeacher" resultType="map">
select s.*,t.name as tname from student s,teacher t where t.id = s.tid
</select>
</mapper>
- Mapper接口
public interface StudentMapper {
List<HashMap> getByTeacher();
}
测试
@Test
public void getByTeacher(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
List<HashMap> studentList = mapper.getByTeacher();
for (Map student : studentList) {
//通过get方法可以直接取出来
System.out.print(student.get("id")+" ");
System.out.print(student.get("name")+" ");
System.out.print(student.get("tid")+" ");
System.out.print(student.get("tname")+" ");
System.out.println();
}
sqlSession.close();
}

3.这个方式如果只是做一些统计应该会比较好用,但是如果像这种情况还不如直接在Student里加一个temp属性,这样还能直接把List的泛型设置为Student,操作Student时还更方便。
4.但是以下两种情况就不好用了:
如果实体类里的属性是另一个实体类对象时,比如Student里有一个Teacher对象的属性。

又或者是实体类里的属性是另一个实体类的容器,比如Teacher里有一个Student的List。

这时候就要使用结果集映射的对象(associtation )和集合(collection)属性。
我的理解其实就是把普通结果集映射的properties替换成associtation而已,感觉就像是在xml文件里也定义了一个实体类,其中对象要用associtation来定义。
associtation
一、按照查询嵌套处理
Student里给了Teacher对象
//省略了无参、有参构造、get、set、重写toString
public class Student {
private int id;
private String name;
private int tid;
private Teacher teacher;
}
public class Teacher {
private int id;
private String name;
}
Mapper接口
public interface StudentMapper {
//获取所有学生的信息
List<Student> getAllStudent();
}
Mapper.xml
<mapper namespace="com.rzp.dao.StudentMapper">
<!--查询所有学生和对应的老师,思路:
1.查询所有的学生信息
2.根据查询出来的学生tid寻找对应的老师
-->
<select id="getAllStudent" resultMap="StudentMap">
select * from student
</select>
<resultMap id="StudentMap" type="Student">
<!--复杂的属性,需要单独处理 对象:associtation 集合:collection-->
<!--结果集映射中定义一个“对象”(associtation)属性
property---student中这个对象的名称
javaType---student中这个对象的类
select---获取这个对象的查询语句(方法)
column---使用这个语句要输入的参数,多个是column="{prop1=col1,prop2=col2}"
-->
<association property="teacher" column="tid" javaType="Teacher" select="getAllStudendTest"/>
</resultMap>
<select id="getAllStudendTest" resultType="Teacher">
select * from teacher where id = #{id}
</select>
</mapper>
测试方法
//查询所有学生
@Test
public void getAllTeacher(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
List<Student> studentList = mapper.getAllStudent();
for (Student student : studentList) {
System.out.println(student);
}
sqlSession.close();
}
这个方式个人感觉不太符合一般联表查询的思维,更加像嵌套子查询。
二、按照结果嵌套处理
Mapper接口
//按照结果嵌套处理
List<Student> getAllStudent2();
Mapper.xml
<select id="getAllStudent2" resultMap="StudentMap2">
select s.id,s.name,s.tid,t.name tname
from student s,teacher t
where s.tid = t.id
</select>
<resultMap id="StudentMap2" type="Student">
<result property="id" column="id"/>
<result property="name" column="name"/>
<result property="tid" column="tid"/>
<association property="teacher" javaType="Teacher">
<result property="name" column="tname"/>
</association>
</resultMap>
测试
//查询所有学生2
@Test
public void getAllTeacher2(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
List<Student> studentList = mapper.getAllStudent2();
for (Student student : studentList) {
System.out.println(student);
}
sqlSession.close();
}

备注:测试结果之中,teacher对象的id是0,个人觉得这个很像一个有参构造器。

collection
三、按照结果嵌套处理
实体类
public class Student {
private int id;
private String name;
private int tid;
}
public class Teacher {
private int id;
private String name;
private List<Student> studentsList;
}
Mapper.xml
<!--按结果嵌套查询-->
<select id="getTeacherById" resultMap="TeacherMap">
select s.*,t.name tname from student s,teacher t
where s.tid = t.id and t.id = #{tid}
</select>
<resultMap id="TeacherMap" type="Teacher">
<result property="name" column="tname"/>
<collection property="studentsList" ofType="Student" >
<result property="id" column="id"/>
<result property="name" column="name"/>
<result property="tid" column="tid"/>
</collection>
</resultMap>
Mapper接口
Teacher getTeacherById(@Param("tid") int id);
测试
@Test
public void test1(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
TeacherMapper mapper = sqlSession.getMapper(TeacherMapper.class);
Teacher teacher = mapper.getTeacherById(1);
System.out.println(teacher);
sqlSession.close();
}

四、按查询嵌套处理
Mapper.xml
<!--按查询嵌套处理-->
<select id="getTeacherById2" resultMap="TeacherMap1">
select t.* from teacher t where t.id = #{id}
</select> <resultMap id="TeacherMap1" type="Teacher">
<result property="id" column="id"/>
<!--ofType--泛型-->
<collection property="studentsList" javaType="ArrayList" ofType="Student" column="id" select="getStudent"/>
</resultMap> <select id="getStudent" resultType="Student">
select * from student where tid = #{id}
</select>
Mapper接口
Teacher getTeacherById2(int id);
测试
@Test
public void test2(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
TeacherMapper mapper = sqlSession.getMapper(TeacherMapper.class);
Teacher teacher = mapper.getTeacherById2(1);
System.out.println(teacher);
sqlSession.close();
}

对比
按结果查询,sql复杂,查询次数少,xml结构简单。
按查询嵌套处理,sql简单,查询了多次,xml结构复杂。
个人觉得按结果查询更简单,xml结构复杂可能很难排错。
MyBatis(八):高级结果映射的更多相关文章
- mybatis之高级结果映射
先贴一句官方文档内容 如果世界总是这么简单就好了. 正如官方文档所说:如果一切都是这么简单,那该多好啊,但是实际上,我们面对的是复杂的对象,就是对象里有对象,有列表对象,总之五花八门的对象.这个时候我 ...
- 深入浅出Mybatis系列(八)---mapper映射文件配置之select、resultMap
上篇<深入浅出Mybatis系列(七)---mapper映射文件配置之insert.update.delete>介绍了insert.update.delete的用法,本篇将介绍select ...
- 深入浅出Mybatis系列(八)---mapper映射文件配置之select、resultMap good
上篇<深入浅出Mybatis系列(七)---mapper映射文件配置之insert.update.delete>介绍了insert.update.delete的用法,本篇将介绍select ...
- 深入浅出Mybatis系列(八)---mapper映射文件配置之select、resultMap[转]
上篇<深入浅出Mybatis系列(七)---mapper映射文件配置之insert.update.delete>介绍了insert.update.delete的用法,本篇将介绍select ...
- MyBatis从入门到精通(第6章):MyBatis 高级查询->6.1.2高级结果映射之一对多映射
jdk1.8.MyBatis3.4.6.MySQL数据库5.6.45.IntelliJ IDEA 2019.3.1 本章主要包含的内容为 MyBatis 的高级结果映射,主要处理数据库一对一.一对多的 ...
- MyBatis从入门到精通(第6章):MyBatis 高级查询->6.1.1高级结果映射之一对一映射
jdk1.8.MyBatis3.4.6.MySQL数据库5.6.45.IntelliJ IDEA 2019.2.4 本章主要包含的内容为 MyBatis 的高级结果映射,主要处理数据库一对一.一对多的 ...
- MyBatis学习--高级映射
简介 前面说过了简单的数据库查询和管理查询,在开发需求中有一些一对一.一对多和多对多的需求开发,如在开发购物车的时候,订单和用户是一对一,用户和订单是一对多,用户和商品是多对多.这些在Hibernat ...
- Mybatis 高级结果映射 ResultMap Association Collection
在阅读本文章时,先说几个mybatis中容易混淆的地方: 1. mybatis中的列不是数据库里的列而是查询里的列,可以是别名(如 select user_name as userName,这时col ...
- Mybatis学习记录(六)----Mybatis的高级映射
1.一对多查询 1.1 需求 查询订单及订单明细的信息. 1.2 sql语句 确定主查询表:订单表 确定关联查询表:订单明细表 在一对一查询基础上添加订单明细表关联即可. SELECT orders. ...
- Mybatis(四) 高级映射,一对一,一对多,多对多映射
天气甚好,怎能不学习? 一.单向和双向 包括一对一,一对多,多对多这三种情况,但是每一种又分为单向和双向,在hibernate中我们就详细解析过这单向和双向是啥意思,在这里,在重复一遍,就拿一对多这种 ...
随机推荐
- 超强图文|并发编程【等待/通知机制】就是这个feel~
你有一个思想,我有一个思想,我们交换后,一个人就有两个思想 If you can NOT explain it simply, you do NOT understand it well enough ...
- Django 中自定义用户模型及集成认证授权功能总结
1. 概述 Django 中的 django.contrib.auth 应用提供了完整的用户及认证授权功能. Django 官方推荐基于内置 User 数据模型创建新的自定义用户模型,方便添加 bir ...
- vue — 创建vue项目
创建vue项目 在程序开发中,有三种方式创建vue项目,本地引入vuejs.使用cdn引入vuejs.使用vue-cli创建vue项目.其中vue-cli可以结合webpack打包工具使用,大大方便了 ...
- div中单行文字垂直水平居中
1.div中单行文字垂直水平居中.条件:外层div高度已经给定.代码如下: 复制代码代码如下: <style type="text/css">.div3{border: ...
- 数据库-第三章 关系数据库标准语言SQL-3.3 数据查询
数据查询 例: 一.单表查询 1.定义 是指仅涉及一个表的查询 2.选择表中的若干列 查询指定列 例: 查询全部列 例: 查询经过计算的值 例: 3.选择表中的若干元组 消除取值重复的行 例: 查询满 ...
- oracle数据库表用序列实现主键自增长
原理注意:序列和触发器必须建立在同一个用户名下否则运行出错1.建立数据表create table 表名( userid number(10) primary key, ...
- c++ 的vector sort遇到栈错误
在做pat乙级1082 射击比赛时 遇到了sort 段错误. 题目链接:https://www.patest.cn/contests/pat-b-practise/1082 感觉写的没啥毛病 但就是段 ...
- Centos7 搭建 Flume 采集 Nginx 日志
版本信息 CentOS: Linux localhost.localdomain 3.10.0-862.el7.x86_64 #1 SMP Fri Apr 20 16:44:24 UTC 2018 x ...
- Faiss向量相似性搜索
Faiss 快速入门(1) Faiss 更快的索引(2) Faiss低内存占用(3) Faiss 构建: clustering, PCA, quantization(4) 如何选择Faiss索引(5)
- windows找不到文件gpedit.msc处理方法
新建一个txt,输入 @echo offpushd "%~dp0"dir /b C:\Windows\servicing\Packages\Microsoft-Windows-Gr ...