• 多个学生,对应一个老师
  • 对于学生而言,关联:多个学生关联一个老师【多对一】
  • 对于老师而言,集合:一个老师,有多个学生【一对多】

复杂查询环境搭建

数据库搭建

CREATE TABLE `teacher` (
`id` INT(10) NOT NULL,
`name` VARCHAR(30) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=INNODB DEFAULT CHARSET=utf8 INSERT INTO teacher(`id`, `name`) VALUES (1, 秦老师); CREATE TABLE `student` (
`id` INT(10) NOT NULL,
`name` VARCHAR(30) DEFAULT NULL,
`tid` INT(10) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `fktid` (`tid`),
CONSTRAINT `fktid` FOREIGN KEY (`tid`) REFERENCES `teacher` (`id`)
) ENGINE=INNODB DEFAULT CHARSET=utf8INSERT INTO `student` (`id`, `name`, `tid`) VALUES (1, 小明, 1);
INSERT INTO `student` (`id`, `name`, `tid`) VALUES (2, 小红, 1);
INSERT INTO `student` (`id`, `name`, `tid`) VALUES (3, 小张, 1);
INSERT INTO `student` (`id`, `name`, `tid`) VALUES (4, 小李, 1);
INSERT INTO `student` (`id`, `name`, `tid`) VALUES (5, 小王, 1);

创建Maven项目

  • pom.xml配置所使用的依赖
    <!--导入依赖-->
<dependencies>
<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.7</version>
</dependency>
<!--数据库连接-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.22</version>
</dependency>
<!--Junit测试单元-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13</version>
<scope>test</scope>
</dependency>
</dependencies>
  • Mybatis核心配置文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd" >
<!--核心配置文件-->
<configuration>
<!--引入外部配置文件(db.properties)-->
<properties resource="db.properties"/> <settings>
<!--标准日志工厂实现-->
<setting name="logImpl" value="STDOUT_LOGGING"/>
</settings> <!--引入别名(扫描包)-->
<typeAliases>
<package name="cn.iris.pojo"/>
</typeAliases> <!--配置环境-->
<environments default="test">
<environment id="test">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
</environments> </configuration>
  • 创建项目包结构(pojo,dao,utils)
    • pojo
      • Student
      • Teacher
    • Dao
      • StudentMapper
      • TeacherMapper
    • Utils
      • MybatisUtil
package cn.iris.utils;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder; import java.io.IOException;
import java.io.InputStream; // SqlSessionFactory --> SqlSession
public class MybatisUtils { private static SqlSessionFactory sqlSessionFactory; static {
try {
// 使用Mybatis获取SqlSessionFactory对象
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
} catch (IOException e) {
e.printStackTrace();
}
}
// 有了 SqlSessionFactory,我们可以从中获得 SqlSession 的实例
public static SqlSession getSqlSession() {
return sqlSessionFactory.openSession();
} }
  • 编写实体类
    • Class Teacher
package cn.iris.pojo;

public class Teacher {

    private int id;
private String name; public Teacher() {} public Teacher(int id, String name) {
this.id = id;
this.name = name;
} Setter&Getter @Override
public String toString()
}
    • Class Student
package cn.iris.pojo;

public class Student {
private int id;
private String name;
private Teacher teacher; public Student(int id, String name, Teacher teacher) {
this.id = id;
this.name = name;
this.teacher = teacher;
} public Student() {
} Setter&Getter @Override
public String toString()
}
  • 编写与实体类绑定的Mapper.xml
    • resource.cn.iris.dao
    • 一定要在核心配置文件中注册Mapper.xml
<!--以TeacherMapper为例-->
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="cn.iris.dao.TeacherMapper"> </mapper>

测试环境搭建

  • TeacherMapper中测试getTeacherById()方法
// 使用注解进行简单查询测试
@Select("SELECT * FROM teacher WHERE id = #{id}")
Teacher getTeacherById(@Param("id") int id);

多对一 具体代码实现

  • 查询所有学生以及其对应的老师信息

<!--思路:
1. 查询所有的学生信息
2. 根据学生tid 寻找 对应的老师
-->

方法一

  • 查询嵌套【子查询处理】
    <select id="getStudent" resultMap="StudentTeacher">
SELECT * FROM student;
</select> <resultMap id="StudentTeacher" type="Student">
<result property="id" column="id"/>
<result property="name" column="name"/>
<!--复杂属性需要单独处理
对象:association 集合:collection-->
<!--property 属性名
column 字段名
javaType 对应的Java对象(全类名/别名)
select 嵌套查询
-->
<association property="teacher" column="tid" javaType="Teacher" select="getTeacher"/>
</resultMap>
<select id="getTeacher" resultType="Teacher">
SELECT * FROM teacher WHERE id = #{tid};
</select>

方法二

  • 按照结果嵌套处理【SQL联表查询】
    <select id="getStudent2" resultMap="StudentTeacher2">
SELECT s.id sid,s.name sname,t.id tid,t.name tname FROM student s, teacher t
WHERE s.tid = t.id;
</select>
<resultMap id="StudentTeacher2" type="Student">
<result property="id" column="sid"/>
<result property="name" column="sname"/>
<association property="teacher" javaType="Teacher">
<result property="name" column="tname"/>
<result property="id" column="tid"/>
</association>
</resultMap>

一对多 具体代码实现

环境搭建

  • Class Teacher
package cn.iris.pojo;

public class Student {
private int id;
private String name;
private int tid; public Student() {
} public Student(int id, String name, int tid) {
this.id = id;
this.name = name;
this.tid = tid;
} Setter&Getter @Override
public String toString()
}
}
  • Class Student
package cn.iris.pojo;

import java.util.List;

public class Teacher {

    private int id;
private String name;
private List<Student> students; public Teacher(){} public Teacher(int id, String name, List<Student> students) {
this.id = id;
this.name = name;
this.students = students;
} Setter&Getter @Override
public String toString()
}
}
  • 查询指定ID老师及其全部学生

    • 【联表查询】结果集嵌套处理
    <!--按结果嵌套查询-->
<select id="getTeacherStudents" resultMap="TeacherStudent">
SELECT s.id sid, s.name sname, t.id tid,t.name tname FROM student s, teacher t
WHERE s.tid = t.id AND t.id = #{id};
</select> <resultMap id="TeacherStudent" type="Teacher">
<result property="id" column="tid"/>
<result property="name" column="tname"/>
<collection property="students" ofType="Student">
<result property="id" column="sid"/>
<result property="name" column="sname"/>
<result property="tid" column="tid"/>
</collection>
</resultMap>
    • 【子查询】查询嵌套
    <!--子查询-->
<select id="getTeacherStudents2" resultMap="TeacherStudent2">
SELECT * FROM teacher WHERE id = #{id}
</select>
<resultMap id="TeacherStudent2" type="Teacher">
<result property="id" column="id"/>
<result property="name" column="name"/>
<collection property="students" javaType="ArrayList" ofType="Student" select="getStudent" column="id"/>
</resultMap>
<select id="getStudent" resultType="Student">
SELECT * FROM student WHERE tid = #{tid}
</select>

总结

  1. 关联 - association【多对一】
  2. 集合 - collection【一对多】
  3. javaType & ofType
    • javaType:用来指定实体类中属性类型
    • ofType:用来指定指定映射到List/集合中的pojo类型(泛型中的约束类型)
  4. 注意点
    • 确保SQL的可读性(通俗易懂)
    • 注意【一对多】和【多对一】中的属性名&字段问题
    • 如果问题不好排错 --> 使用日志,查看log文件
  5. Mybatis执行流程

【面试涉及问题】

Mybatis学习笔记-复杂查询的更多相关文章

  1. mybatis学习笔记(14)-查询缓存之中的一个级缓存

    mybatis学习笔记(14)-查询缓存之中的一个级缓存 标签: mybatis mybatis学习笔记14-查询缓存之中的一个级缓存 查询缓存 一级缓存 一级缓存工作原理 一级缓存測试 一级缓存应用 ...

  2. Mybatis学习笔记导航

    Mybatis小白快速入门 简介 本人是一个Java学习者,最近才开始在博客园上分享自己的学习经验,同时帮助那些想要学习的uu们,相关学习视频在小破站的狂神说,狂神真的是我学习到现在觉得最GAN的老师 ...

  3. MyBatis:学习笔记(3)——关联查询

    MyBatis:学习笔记(3)--关联查询 关联查询 理解联结 SQL最强大的功能之一在于我们可以在数据查询的执行中可以使用联结,来将多个表中的数据作为整体进行筛选. 模拟一个简单的在线商品购物系统, ...

  4. mybatis学习笔记(10)-一对一查询

    mybatis学习笔记(10)-一对一查询 标签: mybatis mybatis学习笔记10-一对一查询 resultType实现 resultMap实现 resultType和resultMap实 ...

  5. Mybatis学习笔记(二) 之实现数据库的增删改查

    开发环境搭建 mybatis 的开发环境搭建,选择: eclipse j2ee 版本,mysql 5.1 ,jdk 1.7,mybatis3.2.0.jar包.这些软件工具均可以到各自的官方网站上下载 ...

  6. MyBatis:学习笔记(1)——基础知识

    MyBatis:学习笔记(1)--基础知识 引入MyBatis JDBC编程的问题及解决设想 ☐ 数据库连接使用时创建,不使用时就释放,频繁开启和关闭,造成数据库资源浪费,影响数据库性能. ☐ 使用数 ...

  7. Mybatis学习笔记二

    本篇内容,紧接上一篇内容Mybatis学习笔记一 输入映射和输出映射 传递简单类型和pojo类型上篇已介绍过,下面介绍一下包装类型. 传递pojo包装对象 开发中通过可以使用pojo传递查询条件.查询 ...

  8. Mybatis学习笔记之二(动态mapper开发和spring-mybatis整合)

    一.输入映射和输出映射 1.1 parameterType(输入类型) [传递简单类型] 详情参考Mybatis学习笔记之一(环境搭建和入门案例介绍) 使用#{}占位符,或者${}进行sql拼接. [ ...

  9. mybatis学习笔记--常见的错误

    原文来自:<mybatis学习笔记--常见的错误> 昨天刚学了下mybatis,用的是3.2.2的版本,在使用过程中遇到了些小问题,现总结如下,会不断更新. 1.没有在configurat ...

随机推荐

  1. Java 设置Word文本框中的文字旋转方向

    Word文档中可添加文本框,并设置文本框为横向文本排列或是纵向文本排列,或者设置文本框中的文字旋转方向等.通过Java程序代码,也可以实现以上文本框的操作.下面以Java代码示例展示具体的实现步骤.另 ...

  2. vscode中html和vue没有自动补全,需要怎么配置

    先安装HTML Snippets插件 点击 文件-首选项-设置,然后根据以下操作 然后在setting.json中加入以下代码 然后就有提示了

  3. Python-统计目录(文件夹)中Excel文件个数和数据量

    背景:前一阵子在帮客户做Excel文件中的数据处理,但是每周提交周报,领导都需要统计从客户接收的文件数量以及记录数.所以我就简单写了统计的脚本,方便统计目录(文件夹)中的Excel文件个数和数据量. ...

  4. Python的字符串和编码

    1. 字符编码 字符串也是一种数据类型,但是,字符串比较特殊的是还有一个编码问题. 因为计算机只能处理数字,如果要处理文本,就必须先把文本转换为数字才能处理.最早的计算机在设计时采用8个比特(bit) ...

  5. mapboxgl 互联网地图纠偏插件(二)

    前段时间写的mapboxgl 互联网地图纠偏插件(一)存在地图旋转时瓦片错位的问题. 这次没有再跟 mapboxgl 的变换矩阵较劲,而是另辟蹊径使用 mapboxgl 的自定义图层,重新写了一套加载 ...

  6. Nginx跨域了解及模拟和解决

    Nginx跨域 同源策略 何为同源: 1.协议(http/https)相同 2.域名(IP)相同 3.端口相同 详解请看我另一篇文章 https://www.cnblogs.com/you-men/p ...

  7. hdu 6092 Rikka with Subset 01背包 思维

    dp[i][j]表示前i个元素,子集和为j的个数.d[i][j] = d[i][j] + d[i-1][j-k] (第i个元素的值为k).这里可以优化成一维数组 比如序列为 1 2 3,每一步的dp值 ...

  8. ES2021 新特性!

    大家好,我是前端队长Daotin,想要获取更多前端精彩内容,关注我(全网同名),解锁前端成长新姿势. 以下正文: 2021 年 6 月 22 日,第 121 届 Ecma 国际(Ecma Intern ...

  9. ABP Framework 为什么好上手,不好深入?探讨最佳学习姿势!

    离写上一篇经验总结 ABP Framework 研习社经验总结(6.28-7.2) ,已经过去两周. ABP Framework 研习社(QQ群:726299208) 最近一周,又迎来了很多新伙伴,成 ...

  10. ESP32-使用有刷直流电机笔记

    基于ESP-IDF4.1 1 /* 2 * 刷直流电动机控制示例,代码通过L298电机芯片测试 3 */ 4 5 #include <stdio.h> 6 7 #include " ...