Mybatis学习笔记-复杂查询

- 多个学生,对应一个老师
- 对于学生而言,关联:多个学生关联一个老师【多对一】
- 对于老师而言,集合:一个老师,有多个学生【一对多】
复杂查询环境搭建
数据库搭建
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>
总结
- 关联 - association【多对一】
- 集合 - collection【一对多】
- javaType & ofType
- javaType:用来指定实体类中属性类型
- ofType:用来指定指定映射到List/集合中的pojo类型(泛型中的约束类型)
- 注意点
- 确保SQL的可读性(通俗易懂)
- 注意【一对多】和【多对一】中的属性名&字段问题
- 如果问题不好排错 --> 使用日志,查看log文件
- Mybatis执行流程

【面试涉及问题】
- Mysql引擎
https://www.jianshu.com/p/4bb9f78b4f6d - InnoDB底层原理
https://www.jianshu.com/p/9b83ea78b380 - 索引&索引优化
https://www.cnblogs.com/kexinxin/p/11537898.html
Mybatis学习笔记-复杂查询的更多相关文章
- mybatis学习笔记(14)-查询缓存之中的一个级缓存
mybatis学习笔记(14)-查询缓存之中的一个级缓存 标签: mybatis mybatis学习笔记14-查询缓存之中的一个级缓存 查询缓存 一级缓存 一级缓存工作原理 一级缓存測试 一级缓存应用 ...
- Mybatis学习笔记导航
Mybatis小白快速入门 简介 本人是一个Java学习者,最近才开始在博客园上分享自己的学习经验,同时帮助那些想要学习的uu们,相关学习视频在小破站的狂神说,狂神真的是我学习到现在觉得最GAN的老师 ...
- MyBatis:学习笔记(3)——关联查询
MyBatis:学习笔记(3)--关联查询 关联查询 理解联结 SQL最强大的功能之一在于我们可以在数据查询的执行中可以使用联结,来将多个表中的数据作为整体进行筛选. 模拟一个简单的在线商品购物系统, ...
- mybatis学习笔记(10)-一对一查询
mybatis学习笔记(10)-一对一查询 标签: mybatis mybatis学习笔记10-一对一查询 resultType实现 resultMap实现 resultType和resultMap实 ...
- Mybatis学习笔记(二) 之实现数据库的增删改查
开发环境搭建 mybatis 的开发环境搭建,选择: eclipse j2ee 版本,mysql 5.1 ,jdk 1.7,mybatis3.2.0.jar包.这些软件工具均可以到各自的官方网站上下载 ...
- MyBatis:学习笔记(1)——基础知识
MyBatis:学习笔记(1)--基础知识 引入MyBatis JDBC编程的问题及解决设想 ☐ 数据库连接使用时创建,不使用时就释放,频繁开启和关闭,造成数据库资源浪费,影响数据库性能. ☐ 使用数 ...
- Mybatis学习笔记二
本篇内容,紧接上一篇内容Mybatis学习笔记一 输入映射和输出映射 传递简单类型和pojo类型上篇已介绍过,下面介绍一下包装类型. 传递pojo包装对象 开发中通过可以使用pojo传递查询条件.查询 ...
- Mybatis学习笔记之二(动态mapper开发和spring-mybatis整合)
一.输入映射和输出映射 1.1 parameterType(输入类型) [传递简单类型] 详情参考Mybatis学习笔记之一(环境搭建和入门案例介绍) 使用#{}占位符,或者${}进行sql拼接. [ ...
- mybatis学习笔记--常见的错误
原文来自:<mybatis学习笔记--常见的错误> 昨天刚学了下mybatis,用的是3.2.2的版本,在使用过程中遇到了些小问题,现总结如下,会不断更新. 1.没有在configurat ...
随机推荐
- Hive和Spark分区策略
1.概述 离线数据处理生态系统包含许多关键任务,最大限度的提高数据管道基础设施的稳定性和效率是至关重要的.这边博客将分享Hive和Spark分区的各种策略,以最大限度的提高数据工程生态系统的稳定性和效 ...
- [翻译]Go与C#对比 第三篇:编译、运行时、类型系统、模块和其它的一切
Go vs C#, Part 3: Compiler, Runtime, Type System, Modules, and Everything Else | by Alex Yakunin | S ...
- windows下Docker Desktop安装管理
检查要求 Windows 10 企业版.专业版或教育版 (必须windows10 1903版本以上)版本号 18362.1049+ 或 18363.1049+ ,次版本#大于.1049.最好是最新版( ...
- Redis的数据安全与性能保障
1.持久化选项 Redis提供了2种不同的持久化方法来将数据存储到硬盘里面.一种方法叫快照(snapshotting),它可以将存在于某一时刻的所有数据都写入硬盘里.另一种方法叫只追加文件(appen ...
- 双向链表(DoubleLinkList)
双向链表 有关链表的知识可以点击我上篇文章这里就不再赘述LinkedList 双向链表也叫双链表,是链表的一种,它的每个数据结点中都有两个指针,分别指向直接后继和直接前驱.所以,从双向链表中的任意一个 ...
- 附加数据库出现 无法打开物理文件 操作系统错误 5:拒绝访问 SQL
刚刚从公司的电脑上考到自己刚刚装好系统的笔记本上面,出现了问题: 无法打开物理文件 操作系统错误 5:拒绝访问 . 网上找了下解决方法: 找到需要导入的 mdf和ldf 修改它的权限为完全控制,不 ...
- [小技巧] google map使用
在网页中打开 google map 中,可以使用 shift + - 来缩小地图,shift + + 来放大地图.
- spring集成flyway
最近给公司项目集成flyway,由于我们项目移动端使用的是spring框架,网上看了很多博客,感觉这方面的东西还是很少的,毕竟现在是springboot的天下,大多数都是springboot集成fly ...
- 计算机基础 | 文档神器docsify安装及基本使用
为啥要用docsify? 神器Docsify让你的文档变得美观,配合typora,从此爱上看文档,各种优点:小巧.快速.美观.方便.快捷.上手快,可以浏览如下优秀案例 ve-charts pyecha ...
- ArcnLinux安装基础配置(二)
本文为对此ArchLinux安装使用教程网站中部分内容的总结和扩展补充,想看更详细的内容可以去此网站. 添加一个用户 useradd -m -G wheel -s /bin/bash cirry 设置 ...