本文是按照狂神说的教学视频学习的笔记,强力推荐,教学深入浅出一遍就懂!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. 【opencv系列02】OpenCV4.X图像读取与显示

    一.读取图片 opencv中采用imread() 函数读取图像 imread(filename, flags=None)     filename 图片的路径     flags 图像读取方式 ● c ...

  2. Java序列化和反序列化-(新手)

    实例: lx1: import java.io.*; public class xuliehua { public static void main(String[] args) throws Exc ...

  3. oracle中plsql练习题-----编写一个PL/SQL块,输出所有员工的员工姓名、员工号、工资和部门号

    一.思路:首先输出需要变量接收,需要声明变量,于是考虑什么变量类型比较合适,在这我用的是table类型,最后,查询出来,循环输出即可. 二.具体实现 -- 编写一个PL/SQL块,输出所有员工的员工姓 ...

  4. 选择tomcat时候提示Project facet Java version 1.8 is not supported.解决办法

    是因为jdk版本不一致导致的,如何解决? 方法一: 选中项目Properties,选择Project Facets,右击选择Java,Change Version 方法二: 在项目的目录下有一个.se ...

  5. .NET 5 Preview 1的深度解读和跟进

    这几天微软.NET 团队发布了.NET 5 Preview-1, 如约而至.很兴奋,因为.NET Core和.NET Framework终于实现了大一统,同时也很期待,期待.NET 5能给我们带来哪些 ...

  6. 直方图均衡算法(Histogram Equalized)

    Lab1: Histogram Equalization 1. 实验环境(C++) 操作系统版本 MacOS Catalina 10.15 OpenCV4.0 (imgcodecs | core | ...

  7. Django之路由层和视图层详解

    路由层 首先我们来看一下,路由层都有哪些东西,其实你看django很人性化,将所有的介绍都放在了简介里面,不信,你看

  8. POJ3352 Road Construction Tarjan+边双连通

    题目链接:http://poj.org/problem?id=3352 题目要求求出无向图中最少需要多少边能够使得该图边双连通. 在图G中,如果任意两个点之间有两条边不重复的路径,称为“边双连通”,去 ...

  9. 使用wrd2vec构建推荐系统

    概览 完整的代码可以从这里下载: https://github.com/prateekjoshi565/recommendation_system/blob/master/recommender_2. ...

  10. (线段树 -星星等级)Stars POJ - 2352

    题意: 给出n个星星的坐标 x,y ,当存在其他星星的坐标x1,y1满足x>=x1&&y>=y1时 这个星星的等级就加1. 注意: 题中给的数据是有规律的 ,y是逐渐增加的 ...