目录
一、创建复杂的查询环境
环境准备具体步骤
-
在项目的
pom.xml
中导入MyBatis需要的依赖; -
创建MyBatis的核心配置文件:
mybatis-config.xml
; -
创建相应实体类:
Thacher.java
和Student.java
; -
创建接口
TeacherMapper.java
和StudentMapper.java
; -
创建对应的映射配置文件
TeacherMapper.xml
和StudentMapper.xml;
-
代码测试;
需要提前建立两张表:student
和 teacher
表。
-- 创建数据库 mybatis01
CREATE DATABASE IF NOT EXISTS `mybatis01`;
USE `mybatis01`;
-- 创建 teacher 表
CREATE TABLE IF NOT EXISTS `teacher` (
`id` INT(10) NOT NULL,
`name` VARCHAR(30) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=INNODB DEFAULT CHARSET=utf8mb4;
-- 插入数据
INSERT INTO `teacher` (`id`, `name`) VALUES (1, '张老师'), (2, '王老师');
-- 创建 student 表
CREATE TABLE IF NOT EXISTS `student` (
`id` INT(10) NOT NULL,
`name` VARCHAR(30) DEFAULT NULL,
`tid` INT(10) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `fktid` (`tid`)
) ENGINE=INNODB DEFAULT CHARSET=utf8mb4;
-- 插入数据
INSERT INTO `student` (`id`, `name`, `tid`) VALUES
(1, '小明', 1),
(2, '小红', 1),
(3, '小张', 2),
(4, '小李', 2),
(5, '小王', 2);
搭建项目环境
二、多表查询
1. 多对一:关联
上述创建的环境中,Teacher
表 和 Student
表,多个学生对应一个班主任。案例查询全部学生(多)的对应班主任(少);
(1)联表查询:
联合查询通常在需要从多个表中检索数据并将它们合并成一个结果集时使用。通常,这种查询在数据库中执行,用于检索相关联的数据,例如在一个学校数据库中,如果你想要检索特定教师和他们教授的课程以及学生信息,你可以使用联合查询。比如,你可以通过教师表中的教师ID关联到课程表中的教师ID,然后再通过课程表中的课程ID关联到学生选课表中的课程ID,最终检索出特定教师教授的课程以及这些课程的学生信息。
思路:先编写SQL语句,保证可以执行,之后再Mapper.xml
文件中 使用resultMap
进行结果的映射。
SELECT s.`id` AS '学生id', s.`name` AS '学生姓名', s.`tid` AS '老师id', t.`name` AS '老师姓名'
FROM `student` AS s
INNER JOIN `teacher` AS t
ON s.`tid` = t.`id`;
编写到Mapper.xml 文件中
<select id="getAllStudents" resultMap="studentResultMap">
SELECT s.`id` AS '学生id', s.`name` AS '学生姓名', s.`tid` AS '老师id', t.`name` AS '老师姓名'
FROM `student` AS s
INNER JOIN `teacher` AS t
ON s.`tid` = t.`id`;
</select>
<resultMap id="studentResultMap" type="Student">
<result property="id" column="学生id"/>
<result property="name" column="学生姓名"/>
<!-- 复杂类型是对象,用 association -->
<association property="teacher" javaType="Teacher">
<result property="id" column="老师id"/>
<result property="name" column="老师姓名"/>
</association>
</resultMap>
代码测试:
(2)子查询
<select id="getAllStudents" resultMap="studentResultMap">
select * from `student`;
</select>
<resultMap id="studentResultMap" type="Student">
<result property="id" column="id"/>
<result property="name" column="name"/>
<association property="teacher" column="tid" javaType="Teacher" select="getTeacher"/>
</resultMap>
<select id="getTeacher" resultType="Teacher">
select * from teacher where `id` = #{tid};
</select>
思路:子查询是按照查询过程嵌套处理;
2、采用一对多的方式(集合)
在 Teacher.java
中添加 Student
类型的集合
思路:同上;
SQL语句:
SELECT t.`id` AS '老师id', t.`name` AS '老师姓名', s.`id` AS '学生id', s.`name` AS '学生姓名'
FROM `teacher` AS t
INNER JOIN `student` AS s
ON t.`id` = s.`tid`;
编写到Mapper.xml
文件中
<select id="getAllTeachers" resultMap="teacherResultMap">
SELECT t.`id` AS '老师id', t.`name` AS '老师姓名', s.`id` AS '学生id', s.`name` AS '学生姓名'
FROM `teacher` AS t
INNER JOIN `student` AS s
ON t.`id` = s.`tid`;
</select>
<resultMap id="teacherResultMap" type="Teacher">
<result property="id" column="老师id"/>
<result property="name" column="老师姓名"/>
<collection property="studentList" ofType="Student">
<result property="id" column="学生id"/>
<result property="name" column="学生姓名"/>
</collection>
</resultMap>
三、缓存
1、简介
MyBatis 是一个优秀的持久层框架,它可以自定义 SQL、存储过程和高级映射。MyBatis 提供了一级缓存和二级缓存两种缓存机制。一级缓存是基于 SqlSession 的,它默认开启且不可关闭,可以提高相同 SqlSession 内相同 SQL 查询的性能。而二级缓存是基于 Mapper 的,它可以跨 SqlSession 共享,需要手动配置开启,并且可以配置缓存的失效策略和刷新机制。
注意:二级缓存只作用于 cache
标签所在的映射文件中的语句。
2、一级缓存
一级缓存时 sqlSession
级别的缓存,默认情况下,一级缓存时开启的;
对同一个会话的数据进行缓存,(sqlSession
从获取到关闭这一段期间的数据)
缓存实现的前提:
-
进行了增、删、改操作,一定会刷新缓存。
-
查询不同的实现类;
-
手动清理缓存
sqlSession.clearCache();
3、二级缓存
二级缓存是 namespace
级别的缓存,会在整个 Mapper.xml
中生效。需要手动开启和配置。
工作机制:当关闭会话时,一级缓存中的数据才会被保存到二级缓存中,新的会话查询信息时,就可以从二级缓存中获取内容。
开启二级缓存步骤:
在 MyBatis 核心配置文件中进行设置(settings)
,开启全局缓存;
在要使用二级缓存的 Mapper.xml
中加 cache
标签。
4、缓存原理:
开启缓存后,查询的顺序:
-
若开启二级缓存,先看二级缓存中有没有要查询的缓存数据
-
二级缓存没有,查询一级缓存中是否存在缓存的对应数据
-
一级二级缓存都没有才会查询数据库
注:喜欢的朋友可以关注公众号“JAVA学习课堂”方便阅读,内容更丰富哦。