本文是按照狂神说的教学视频学习的笔记,强力推荐,教学深入浅出一遍就懂!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(八):高级结果映射的更多相关文章

  1. mybatis之高级结果映射

    先贴一句官方文档内容 如果世界总是这么简单就好了. 正如官方文档所说:如果一切都是这么简单,那该多好啊,但是实际上,我们面对的是复杂的对象,就是对象里有对象,有列表对象,总之五花八门的对象.这个时候我 ...

  2. 深入浅出Mybatis系列(八)---mapper映射文件配置之select、resultMap

    上篇<深入浅出Mybatis系列(七)---mapper映射文件配置之insert.update.delete>介绍了insert.update.delete的用法,本篇将介绍select ...

  3. 深入浅出Mybatis系列(八)---mapper映射文件配置之select、resultMap good

    上篇<深入浅出Mybatis系列(七)---mapper映射文件配置之insert.update.delete>介绍了insert.update.delete的用法,本篇将介绍select ...

  4. 深入浅出Mybatis系列(八)---mapper映射文件配置之select、resultMap[转]

    上篇<深入浅出Mybatis系列(七)---mapper映射文件配置之insert.update.delete>介绍了insert.update.delete的用法,本篇将介绍select ...

  5. MyBatis从入门到精通(第6章):MyBatis 高级查询->6.1.2高级结果映射之一对多映射

    jdk1.8.MyBatis3.4.6.MySQL数据库5.6.45.IntelliJ IDEA 2019.3.1 本章主要包含的内容为 MyBatis 的高级结果映射,主要处理数据库一对一.一对多的 ...

  6. MyBatis从入门到精通(第6章):MyBatis 高级查询->6.1.1高级结果映射之一对一映射

    jdk1.8.MyBatis3.4.6.MySQL数据库5.6.45.IntelliJ IDEA 2019.2.4 本章主要包含的内容为 MyBatis 的高级结果映射,主要处理数据库一对一.一对多的 ...

  7. MyBatis学习--高级映射

    简介 前面说过了简单的数据库查询和管理查询,在开发需求中有一些一对一.一对多和多对多的需求开发,如在开发购物车的时候,订单和用户是一对一,用户和订单是一对多,用户和商品是多对多.这些在Hibernat ...

  8. Mybatis 高级结果映射 ResultMap Association Collection

    在阅读本文章时,先说几个mybatis中容易混淆的地方: 1. mybatis中的列不是数据库里的列而是查询里的列,可以是别名(如 select user_name as userName,这时col ...

  9. Mybatis学习记录(六)----Mybatis的高级映射

    1.一对多查询 1.1 需求 查询订单及订单明细的信息. 1.2 sql语句 确定主查询表:订单表 确定关联查询表:订单明细表 在一对一查询基础上添加订单明细表关联即可. SELECT orders. ...

  10. Mybatis(四) 高级映射,一对一,一对多,多对多映射

    天气甚好,怎能不学习? 一.单向和双向 包括一对一,一对多,多对多这三种情况,但是每一种又分为单向和双向,在hibernate中我们就详细解析过这单向和双向是啥意思,在这里,在重复一遍,就拿一对多这种 ...

随机推荐

  1. 超强图文|并发编程【等待/通知机制】就是这个feel~

    你有一个思想,我有一个思想,我们交换后,一个人就有两个思想 If you can NOT explain it simply, you do NOT understand it well enough ...

  2. Django 中自定义用户模型及集成认证授权功能总结

    1. 概述 Django 中的 django.contrib.auth 应用提供了完整的用户及认证授权功能. Django 官方推荐基于内置 User 数据模型创建新的自定义用户模型,方便添加 bir ...

  3. vue — 创建vue项目

    创建vue项目 在程序开发中,有三种方式创建vue项目,本地引入vuejs.使用cdn引入vuejs.使用vue-cli创建vue项目.其中vue-cli可以结合webpack打包工具使用,大大方便了 ...

  4. div中单行文字垂直水平居中

    1.div中单行文字垂直水平居中.条件:外层div高度已经给定.代码如下: 复制代码代码如下: <style type="text/css">.div3{border: ...

  5. 数据库-第三章 关系数据库标准语言SQL-3.3 数据查询

    数据查询 例: 一.单表查询 1.定义 是指仅涉及一个表的查询 2.选择表中的若干列 查询指定列 例: 查询全部列 例: 查询经过计算的值 例: 3.选择表中的若干元组 消除取值重复的行 例: 查询满 ...

  6. oracle数据库表用序列实现主键自增长

    原理注意:序列和触发器必须建立在同一个用户名下否则运行出错1.建立数据表create table 表名(           userid number(10) primary key,        ...

  7. c++ 的vector sort遇到栈错误

    在做pat乙级1082 射击比赛时 遇到了sort 段错误. 题目链接:https://www.patest.cn/contests/pat-b-practise/1082 感觉写的没啥毛病 但就是段 ...

  8. 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 ...

  9. Faiss向量相似性搜索

    Faiss 快速入门(1) Faiss 更快的索引(2) Faiss低内存占用(3) Faiss 构建: clustering, PCA, quantization(4) 如何选择Faiss索引(5)

  10. windows找不到文件gpedit.msc处理方法

    新建一个txt,输入 @echo offpushd "%~dp0"dir /b C:\Windows\servicing\Packages\Microsoft-Windows-Gr ...