1、多对一
多个学生对一个老师
- 创建数据库
DROP TABLE IF EXISTS `teacher`;
CREATE TABLE `teacher` (
`id` int NOT NULL,
`name` varchar(30) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3;
INSERT INTO `teacher` VALUES ('1', '秦老师');
DROP TABLE IF EXISTS `student`;
CREATE TABLE `student` (
`id` int NOT NULL,
`name` varchar(30) DEFAULT NULL,
`tid` int DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `fktid` (`tid`),
CONSTRAINT `fktid` FOREIGN KEY (`tid`) REFERENCES `teacher` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `student` VALUES ('1', '小明', '1');
INSERT INTO `student` VALUES ('2', '小红', '1');
INSERT INTO `student` VALUES ('3', '小张', '1');
INSERT INTO `student` VALUES ('4', '小李', '1');
INSERT INTO `student` VALUES ('5', '小王', '1');
- 搭建环境
1、IDEA安装Lombok插件
2、引入Maven依赖
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.22</version>
<scope>provided</scope>
</dependency>
3、新建实体类Teacher,Student在代码中增加注解
@Data //GET,SET,ToString,有参,无参构造
public class Teacher {
private int id;
private String name;
}
@Data
public class Student {
private int id;
private String name;
//多个学生可以是同一个老师,即多对一
private Teacher teacher;
}
4、编写实体类对应的Mapper接口
public interface StudentMapper {
}
public interface TeacherMapper {
}
5、编写Mapper接口对应的 mapper.xml配置文件
<?xml version="1.0" encoding="UTF8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="mapper.StudentMapper">
</mapper>
<?xml version="1.0" encoding="UTF8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="mapper.TeacherMapper">
</mapper>
- 子查询 (按照查询嵌套)
1、给StudentMapper接口增加方法
//获取所有学生及对应老师的信息
public List<Student> getStudents();
2、编写对应的Mapper文件
<?xml version="1.0" encoding="UTF8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="mapper.StudentMapper">
<!--
需求:获取所有学生及对应老师的信息
思路:
1. 获取所有学生的信息
2. 根据获取的学生信息的老师ID->获取该老师的信息
3. 思考问题,这样学生的结果集中应该包含老师,该如何处理呢,数据库中我们一般使用关联查询?
1. 做一个结果集映射:StudentTeacher
2. StudentTeacher结果集的类型为 Student
3. 学生中老师的属性为teacher,对应数据库中为tid。
多个 [1,...)学生关联一个老师=> 一对一,一对多
4. 查看官网找到:association – 一个复杂类型的关联;使用它来处理关联查询
-->
<select id="getStudents" resultMap="StudentTeacher">
select *
from student
</select>
<resultMap id="StudentTeacher" type="Student">
<!--association关联属性 property属性名 javaType属性类型 column在多的一方的表中的列名-->
<association property="teacher" column="tid" javaType="Teacher" select="getTeacher"/>
</resultMap>
<!--
这里传递过来的id,只有一个属性的时候,下面可以写任何值
association中column多参数配置:
column="{key=value,key=value}"
其实就是键值对的形式,key是传给下个sql的取值名称,value是片段一中sql查询的字段名。
-->
<select id="getTeacher" resultType="teacher">
select *
from teacher
where id = #{id}
</select>
</mapper>
3、编写完毕去Mybatis配置文件中,注册Mapper
<?xml version="1.0" encoding="UTF8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<properties resource="db.properties">
</properties>
<typeAliases>
<typeAlias type="pojo.Student" alias="Student"/>
<typeAlias type="pojo.Teacher" alias="Teacher"/>
</typeAliases>
<environments default="development">
<environment id="development">
<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>
<mappers>
<mapper resource="mapper/StudentMapper.xml"/>
</mappers>
</configuration>
测试
package mapper;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
import pojo.Student;
import utils.MybatisUtils;
import java.util.List;
public class MyTest {
@Test
public void testGetStudents() {
SqlSession session = MybatisUtils.getSqlSession();
StudentMapper mapper = session.getMapper(StudentMapper.class);
List<Student> students = mapper.getStudents();
for (Student student : students) {
System.out.println(
"学生名:" + student.getName()
+ "\t老师:" + student.getTeacher().getName());
}
}
}
- 联表查询 (按照结果嵌套)
1、接口方法编写
public List<Student> getStudents2();
2、编写对应的mapper文件
<?xml version="1.0" encoding="UTF8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="mapper.StudentMapper">
<!--
按查询结果嵌套处理
思路:
1. 直接查询出结果,进行结果集的映射
-->
<select id="getStudents2" resultMap="StudentTeacher2">
select s.id sid, s.name sname, t.name tname
from student s,
teacher t
where s.tid = t.id
</select>
<resultMap id="StudentTeacher2" type="Student">
<id property="id" column="sid"/>
<result property="name" column="sname"/>
<!--关联对象property 关联对象在Student实体类中的属性-->
<association property="teacher" javaType="Teacher">
<result property="name" column="tname"/>
</association>
</resultMap>
</mapper>
3、去mybatis-config文件中注入(见上一步配置文件)
4、测试
package mapper;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
import pojo.Student;
import utils.MybatisUtils;
import java.util.List;
public class MyTest {
@Test
public void testGetStudents2(){
SqlSession session = MybatisUtils.getSqlSession();
StudentMapper mapper = session.getMapper(StudentMapper.class);
List<Student> students = mapper.getStudents2();
for (Student student : students){
System.out.println(student
}
}
}
2、一对多
一个老师拥有多个学生
按结果嵌套处理
- 编写实体类
package pojo;
import lombok.Data;
@Data
public class Student {
private int id;
private String name;
private int tid;
}
package pojo;
import lombok.Data;
import java.util.List;
@Data
public class Teacher {
private int id;
private String name;
//一个老师多个学生
private List<Student> students;
}
- 编写接口
package mapper;
import pojo.Teacher;
public interface TeacherMapper {
//获取指定老师,及老师下的所有学生
public Teacher getTeacher(int id);
}
编写接口对应的xml文件
<?xml version="1.0" encoding="UTF8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="mapper.TeacherMapper">
<!--
思路:
1. 从学生表和老师表中查出学生id,学生姓名,老师姓名
2. 对查询出来的操作做结果集映射
1. 集合的话,使用collection!
JavaType和ofType都是用来指定对象类型的
JavaType是用来指定pojo中属性的类型
ofType指定的是映射到list集合属性中pojo的类型。
-->
<select id="getTeacher" resultMap="TeacherStudent">
select s.id sid, s.name sname, t.name tname, t.id tid
from student s,
teacher t
where s.tid = t.id
and t.id = #{id}
</select>
<resultMap id="TeacherStudent" type="Teacher">
<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>
</mapper>
- 将Mapper文件注册到MyBatis-config文件中
<?xml version="1.0" encoding="UTF8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!--外部引入数据库配置文件-->
<properties resource="db.properties">
</properties>
<typeAliases>
<typeAlias type="pojo.Student" alias="Student"/>
<typeAlias type="pojo.Teacher" alias="Teacher"/>
</typeAliases>
<!--environments表示可以里面有很多个运行环境 default表示可以随时切换运行环境-->
<environments default="development">
<environment id="development">
<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>
<mappers>
<mapper resource="mapper/TeacherMapper.xml"/>
</mappers>
</configuration>
- 测试
package mapper;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
import pojo.Teacher;
import utils.MybatisUtils;
public class MyTest {
@Test
public void testGetTeacher() {
SqlSession sqlSession = MybatisUtils.getSqlSession();
TeacherMapper mapper = sqlSession.getMapper(TeacherMapper.class);
Teacher teacher = mapper.getTeacher(1);
System.out.println(teacher.getName());
System.out.println(teacher.getStudents());
}
}
按查询嵌套处理
- 编写接口
package mapper;
import pojo.Teacher;
public interface TeacherMapper {
public Teacher getTeacher2(int id);
}
编写接口对应的xml文件
<?xml version="1.0" encoding="UTF8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="mapper.TeacherMapper">
<select id="getTeacher2" resultMap="TeacherStudent2">
select *
from teacher
where id = #{id}
</select>
<resultMap id="TeacherStudent2" type="Teacher">
<!--column是一对多的外键 , 写的是一的主键的列名-->
<collection property="students" javaType="ArrayList" ofType="Student" column="id"
select="getStudentByTeacherId"/>
</resultMap>
<select id="getStudentByTeacherId" resultType="Student">
select *
from student
where tid = #{id}
</select>
</mapper>
- 配置mybatis-config.xml文件(同上步)
- 测试
package mapper;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
import pojo.Teacher;
import utils.MybatisUtils;
public class MyTest {
@Test
public void testGetTeacher2() {
SqlSession session = MybatisUtils.getSqlSession();
TeacherMapper mapper = session.getMapper(TeacherMapper.class);
Teacher teacher = mapper.getTeacher2(1);
System.out.println(teacher.getName());
System.out.println(teacher.getStudents());
}
}
- 注意事项:
1、关联-association【多对一】
2、集合-collection【一对多】
3、所以association是用于一对一和多对一,而collection是用于一对多的关系
4、JavaType和ofType都是用来指定对象类型的
JavaType是用来指定pojo中属性的类型
ofType指定的是映射到list集合属性中pojo的类型。
3、动态SQL
(是根据不同的查询条件 , 生成不同的Sql语句.)
- 搭建环境
1、创建数据表
CREATE TABLE `blog` (
`id` varchar(50) NOT NULL COMMENT '博客id',
`title` varchar(100) NOT NULL COMMENT '博客标题',
`author` varchar(30) NOT NULL COMMENT '博客作者',
`create_time` datetime NOT NULL COMMENT '创建时间',
`views` int(30) NOT NULL COMMENT '浏览量'
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
2、创建基本的maven工程,结构如下:
3、创建实体类
package pojo;
import lombok.Data;
import java.util.Date;
@Data
public class Blog {
private String id;
private String title;
private String author;
private Date createTime;
private int views;
}
4、导包(maven)
<!--导入依赖-->
<dependencies>
<!--MySQL驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.25</version>
</dependency>
<!--mybatis驱动-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.7</version>
</dependency>
<!--junit驱动-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.22</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>true</filtering>
</resource>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>true</filtering>
</resource>
</resources>
</build>
5、创建接口及接口对应的xml文件
package mapper;
public interface BlogMapper {
}
<?xml version="1.0" encoding="UTF8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="mapper.BlogMapper">
</mapper>
6、新建IDutil工具类(产生的随机UUID中间的 - 换成 空 )
package utils;
import org.junit.Test;
import java.util.UUID;
public class IDUtil {
public static String genId() {
return UUID.randomUUID().toString().replaceAll("-", "");
}
@Test
public void test() {
System.out.println(IDUtil.genId());
}
}
7、配置核心文件
<?xml version="1.0" encoding="UTF8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!--外部引入数据库配置文件-->
<properties resource="db.properties">
</properties>
<settings>
<!-- 下划线驼峰自动转换-->
<setting name="mapUnderscoreToCamelCase" value="true"/>
<!-- 默认日志-->
<setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>
<typeAliases>
<typeAlias type="pojo.Blog" alias="Blog"/>
</typeAliases>
<!--environments表示可以里面有很多个运行环境 default表示可以随时切换运行环境-->
<environments default="development">
<environment id="development">
<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>
<mappers>
<mapper resource="mapper/BlogMapper.xml"/>
</mappers>
</configuration>
- 插入数据
- 编写接口
package mapper;
import pojo.Blog;
public interface BlogMapper {
//新增一个博客
int addBlog(Blog blog);
}
- 接口对应的xml文件
<?xml version="1.0" encoding="UTF8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="mapper.BlogMapper">
<insert id="addBlog" parameterType="Blog">
insert into mybatis.blog (id, title, author, create_time, views)
values (#{id}, #{title}, #{author}, #{createTime}, #{views});
</insert>
</mapper>
- 测试插入数据
package mapper;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
import pojo.Blog;
import utils.IDUtil;
import utils.MybatisUtils;
import java.util.Date;
public class MyTest {
@Test
public void addInitBlog() {
SqlSession session = MybatisUtils.getSqlSession();
BlogMapper mapper = session.getMapper(BlogMapper.class);
Blog blog = new Blog();
blog.setId(IDUtil.genId());
blog.setTitle("java");
blog.setAuthor("ZYH");
blog.setCreateTime(new Date());
blog.setViews(222);
mapper.addBlog(blog);
blog.setId(IDUtil.genId());
blog.setTitle("vue");
mapper.addBlog(blog);
blog.setId(IDUtil.genId());
blog.setTitle("js");
mapper.addBlog(blog);
blog.setId(IDUtil.genId());
blog.setTitle("spring");
mapper.addBlog(blog);
blog.setId(IDUtil.genId());
blog.setTitle("springmvc");
mapper.addBlog(blog);
blog.setId(IDUtil.genId());
blog.setTitle("springboot");
mapper.addBlog(blog);
session.commit();
session.close();
}
}
- if 语句查询
根据作者名字和博客名字来查询博客!
如果作者名字为空,那么只根据博客名字查询,反之,则根据作者名来查询
- 编写接口
List<Blog> queryBlogIf(Map map);
- 编写接口相对应的xml文件
<!--需求1:
根据作者名字和博客名字来查询博客!
如果作者名字为空,那么只根据博客名字查询,反之,则根据作者名来查询
select * from blog where title = #{title} and author = #{author}
-->
<select id="queryBlogIf" parameterType="map" resultType="blog">
select * from blog where
<if test="title != null">
title = #{title}
</if>
<if test="author != null">
and author = #{author}
</if>
</select>
- 测试
@Test
public void testQueryBlogIf() {
SqlSession session = MybatisUtils.getSqlSession();
BlogMapper mapper = session.getMapper(BlogMapper.class);
HashMap<String, String> map = new HashMap<String, String>();
map.put("title", "Mybatis如此简单");
map.put("author", "狂神说");
List<Blog> blogs = mapper.queryBlogIf(map);
System.out.println(blogs);
session.close();
}
- Where
- 编写接口(同上 if语句)
- 编写xml文件
<select id="queryBlogIf" parameterType="map" resultType="blog">
select * from blog
<where>
<if test="title != null">
title = #{title}
</if>
<if test="author != null">
and author = #{author}
</if>
</where>
</select>
目的在于这个“where”标签会知道如果它包含的标签中有返回值的话,它就插入一个‘where’。如果标签返回的内容是以 and 或 or 开头的,则它会去除掉。
- 编写测试(同上 if 语句)
- choose语句
- 编写接口
List<Blog> queryBlogChoose(Map map);
- 编写接口对应的xml文件
<select id="queryBlogChoose" parameterType="map" resultType="blog">
select * from blog
<where>
<choose>
<when test="title != null">
title = #{title}
</when>
<when test="author != null">
and author = #{author}
</when>
<otherwise>
and views = #{views}
</otherwise>
</choose>
</where>
</select>
- 测试
@Test
public void testQueryBlogChoose() {
SqlSession session = MybatisUtils.getSqlSession();
BlogMapper mapper = session.getMapper(BlogMapper.class);
HashMap<String, Object> map = new HashMap<String, Object>();
map.put("title", "Java如此简单");
map.put("author", "狂神说");
map.put("views", 9999);
List<Blog> blogs = mapper.queryBlogChoose(map);
System.out.println(blogs);
session.close();
}
- set
编写接口
//更新博客
int updateBlog(Map map);
编写接口对应的xml文件
<!--注意set是用的逗号隔开-->
<update id="updateBlog" parameterType="map">
update blog
<set>
<if test="title != null">
title = #{title},
</if>
<if test="author != null">
author = #{author}
</if>
</set>
where id = #{id};
</update>
测试
@Test
public void testUpdateBlog() {
SqlSession session = MybatisUtils.getSqlSession();
BlogMapper mapper = session.getMapper(BlogMapper.class);
HashMap<String, String> map = new HashMap<String, String>();
map.put("title", "qwewqewqeSQL");
map.put("author", "zzzzz");
map.put("id", "a20ceba335f64530980faac47ae759a8");
mapper.updateBlog(map);
session.close();
}
sql片段(在接口对应的xml文件中)
有时候可能某个 sql 语句我们用的特别多,为了增加代码的重用性,简化代码,我们需要将这些代码抽取出来,然后使用时直接调用
- 提取的sql片段
<sql id="if-title-author">
<if test="title != null">
title = #{title}
</if>
<if test="author != null">
and author = #{author}
</if>
</sql>
- 引用sql片段
<select id="queryBlogIf" parameterType="map" resultType="blog">
select * from blog
<where>
<!-- 引用 sql 片段,如果refid 指定的不在本文件中,那么需要在前面加上 namespace -->
<include refid="if-title-author"></include>
<!-- 在这里还可以引用其他的 sql 片段 -->
</where>
</select>
最好基于 单表来定义 sql 片段,提高片段的可重用性
在 sql 片段中不要包括 where
- foreach
编写接口
List<Blog> queryBlogForeach(Map map);
编写接口对应的xml文件
<select id="queryBlogForeach" parameterType="map" resultType="blog">
select * from blog
<where>
<!--
collection:指定输入对象中的集合属性
item:每次遍历生成的对象
open:开始遍历时的拼接字符串
close:结束时拼接的字符串
separator:遍历对象之间需要拼接的字符串
select * from blog where 1=1 and (id=1 or id=2 or id=3)
-->
<foreach collection="ids" item="id" open="and (" close=")" separator="or">
id=#{id}
</foreach>
</where>
</select>
测试
@Test
public void testQueryBlogForeach() {
SqlSession session = MybatisUtils.getSqlSession();
BlogMapper mapper = session.getMapper(BlogMapper.class);
HashMap map = new HashMap();
List<Integer> ids = new ArrayList<Integer>();
ids.add(1);
ids.add(2);
ids.add(3);
map.put("ids", ids);
List<Blog> blogs = mapper.queryBlogForeach(map);
System.out.println(blogs);
session.close();
}
4、缓存
- 一级缓存(SqlSession级)
1、创建新的MyBatis的maven项目。(核心配置文件,工具类,测试类)
2、创建实体类
package pojo;
import lombok.Data;
@Data
public class User {
private int id;
private String name;
private String pwd;
}
3、编写实体类接口
package mapper;
import org.apache.ibatis.annotations.Param;
import pojo.User;
public interface UserMapper {
//根据id查询用户
User queryUserById(@Param("id") int id);
}
4、编写实体类接口对应的xml文件
<?xml version="1.0" encoding="UTF8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="mapper.UserMapper">
<select id="queryUserById" resultType="user">
select *
from user
where id = #{id}
</select>
</mapper>
5、配置文件中注册xml
6、测试
package mapper;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
import pojo.User;
import utils.MybatisUtils;
public class MyTest {
@Test
public void testQueryUserById() {
SqlSession session = MybatisUtils.getSqlSession();
UserMapper mapper = session.getMapper(UserMapper.class);
User user = mapper.queryUserById(1);
System.out.println(user);
User user2 = mapper.queryUserById(1);
System.out.println(user2);
System.out.println(user == user2);
session.close();
}
}
7、结果分析
- 一级缓存失效的四种情况
查询不同的东西
增删改操作,可能会改变原来的数据,所以必定会刷新缓存!
查询不同的Mapper.xml
手动清理缓存!
sqlSession不同查询条件相同
@Test
public void testQueryUserById(){
SqlSession session = MybatisUtils.getSession();
SqlSession session2 = MybatisUtils.getSession();
UserMapper mapper = session.getMapper(UserMapper.class);
UserMapper mapper2 = session2.getMapper(UserMapper.class);
User user = mapper.queryUserById(1);
System.out.println(user);
User user2 = mapper2.queryUserById(1);
System.out.println(user2);
System.out.println(user==user2);
session.close();
session2.close();
}
sqlSession相同,查询条件不同
@Test
public void testQueryUserById(){
SqlSession session = MybatisUtils.getSession();
UserMapper mapper = session.getMapper(UserMapper.class);
UserMapper mapper2 = session.getMapper(UserMapper.class);
User user = mapper.queryUserById(1);
System.out.println(user);
User user2 = mapper2.queryUserById(2);
System.out.println(user2);
System.out.println(user==user2);
session.close();
}
sqlSession相同,两次查询之间执行了增删改操作!
接口
//修改用户
int updateUser(Map map);
xml
<update id="updateUser" parameterType="map">
update user set name = #{name} where id = #{id}
</update>
测试
@Test
public void testQueryUserById(){
SqlSession session = MybatisUtils.getSession();
UserMapper mapper = session.getMapper(UserMapper.class);
User user = mapper.queryUserById(1);
System.out.println(user);
HashMap map = new HashMap();
map.put("name","kuangshen");
map.put("id",4);
mapper.updateUser(map);
User user2 = mapper.queryUserById(1);
System.out.println(user2);
System.out.println(user==user2);
session.close();
}
sqlSession相同,手动清除一级缓存
@Test
public void testQueryUserById(){
SqlSession session = MybatisUtils.getSession();
UserMapper mapper = session.getMapper(UserMapper.class);
User user = mapper.queryUserById(1);
System.out.println(user);
session.clearCache();//手动清除缓存
User user2 = mapper.queryUserById(1);
System.out.println(user2);
System.out.println(user==user2);
session.close();
}
- 二级缓存(namespace级别)
开启缓存(xml配置文件中配置)
<setting name="cacheEnabled" value="true"/>
接口对应的xml中添加
<!-- 官方示例=====>查看官方文档-->
<cache
eviction="FIFO"
flushInterval="60000"
size="512"
readOnly="true"/>
<!-- 这个更高级的配置创建了一个 FIFO 缓存,每隔 60 秒刷新,最多可以存储结果对象或列表的 512 个引用,而且返回的对象被认为是只读的,因此对它们进行修改可能会在不同线程中的调用者产生冲突。-->
测试
@Test
public void testQueryUserById(){
SqlSession session = MybatisUtils.getSession();
SqlSession session2 = MybatisUtils.getSession();
UserMapper mapper = session.getMapper(UserMapper.class);
UserMapper mapper2 = session2.getMapper(UserMapper.class);
User user = mapper.queryUserById(1);
System.out.println(user);
session.close();
User user2 = mapper2.queryUserById(1);
System.out.println(user2);
System.out.println(user==user2);
session2.close();
}
只要开启了二级缓存,我们在同一个Mapper中的查询,可以在二级缓存中拿到数据
查出的数据都会被默认先放在一级缓存中
只有会话提交或者关闭以后,一级缓存中的数据才会转到二级缓存中
- 缓存原理