本文是按照狂神说的教学视频学习的笔记,强力推荐,教学深入浅出一遍就懂!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. chrome 和 chromeDriver

    在写selenium的时候,发现很简单的case也报错 package com.lv.test; import org.junit.Test; import org.openqa.selenium.W ...

  2. 波兰政府在继韩国之后也增加了对 Linux 的使用

    导读 前段时间, 韩国政府起草了一项战略,准备采用基于 Linux 的开源操作系统全面取代 Windows 7,以摆脱对其的依赖. 目前,波兰的社会保险公司 ZUS( Zakład Ubezpiecz ...

  3. mysql那些事之索引篇

    mysql那些事之索引篇 上一篇博客已经简单从广的方面介绍了一下mysql整体架构以及物理结构的内容. 本篇博客的内容是mysql的索引,索引无论是在面试还是我们日常工作中都是非常的重要一环. 索引是 ...

  4. Natas18 Writeup(Session登录,暴力破解)

    Natas18: 一个登录界面,查看源码,发现没有连接数据库,使用Session登录,且$maxid设定了不大的上限,选择采取爆破. 源码解析: <html> <head> & ...

  5. Fiddler2 下断点修改HTTP报文

    一 Fiddler中设置断点修改HTTP请求 方法1:全局断点.Rules-->Automatic BreakPoint-->Before Requests(或快捷键F11),这种方法会拦 ...

  6. Spring框架——AOP

    Spring AOP 面向切面编程,OOP面向对象编程,将程序中所有参与模块都抽象成对象,然后通过对象之间的相互调用完成需求. AOP是OOP的一种补充,是在另外一个维度上抽象出对象,具体是指程序运行 ...

  7. Python Django撸个WebSSH操作Kubernetes Pod

    优秀的系统都是根据反馈逐渐完善出来的 上篇文章介绍了我们为了应对安全和多分支频繁测试的问题而开发了一套Alodi系统,Alodi可以通过一个按钮快速构建一套测试环境,生成一个临时访问地址,详细信息可以 ...

  8. 如何编写shellcode

    ShellCode的编写就是将函数或变量在内存中的间接地址改为函数或变量在内存中的直接地址,直接调用! 以MessageBox函数为例进行讲解如下 新建shellcode.cpp: 编写代码如下: 运 ...

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

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

  10. JSP(二)----指令,注释,内置对象

    ##  JSP 1.指令 *  作用:用于配置JSP页面,导入资源文件 *  格式: <%@  指令名称  属性名1=属性值1  属性名2=属性值2  %> <%@ page con ...