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 ...
随机推荐
- Jetpack Compose和View的互操作性
Jetpack Compose Interoperability Compose风这么大, 对于已有项目使用新技术, 难免会担心兼容性. 对于Compose来说, 至少和View的结合是无缝的. (目 ...
- c#在类中使用session
先要继承页面的System.Web.UI.Page using System; using System.Collections.Generic; using System.Linq; using S ...
- 第二篇CTF-MISC
第一篇写成了日记,发布不了.第一篇CTF-MISC 04.坚持60S 附件下载下来,是个jar的文件,打开 耶?这是嘛呀? 反正没看懂,既然是jar文件,直接上jd-gui反编译一波试试 这么明显的f ...
- 深入学习Netty(1)——传统BIO编程
前言 之前看过Dubbo源码,Nacos等源码都涉及到了Netty,虽然遇到的时候查查资料,后面自己也有私下学习Netty并实践,但始终没有形成良好的知识体系,Netty对想要在Java开发上不断深入 ...
- 26、mysqlsla慢查询日志分析工具
1.介绍: mysqlsla是hackmysql.com推出的一款MySQL的日志分析工具,可以分析mysql的慢查询日志.分析慢查询非常好用,能针 对库分析慢查询语句的执行频率.扫描的数据量.消耗时 ...
- SpringCloud 微服务最佳开发实践
Maven规范 所有项目必须要有一个统一的parent模块 所有微服务工程都依赖这个parent,parent用于管理依赖版本,maven仓库,jar版本的统一升级维护 在parent下层可以有 co ...
- SDLC开发安全流程
2020年12月9日跟内部小伙伴分享SDLC流程及安全的一些思考,简单画了一个图,时间过得太快,记录一下 参考 https://blog.csdn.net/liqiuman180688/article ...
- Vue 动态参数
v-on和v-bind可以动态绑定一个参数,用[]来绑定一个可以改变的值. <li v-on:[event]="print"></li> <scrip ...
- Nginx:Nginx的安装
Nginx安装 首先安装依赖 #安装Nginx需要gcc openssl-devel pcre-devel zlib-devel依赖 yum -y install gcc openssl-devel ...
- mysql 去重的两种方式
1.distinct一般用于获取不重复字段的条数 使用原则: 1)distinct必须放在要查询字段的开头,不能放在查询字段的中间或者后面 select distinct name from user ...