MyBatis的二级缓存

二级缓存的原理

二级缓存的原理和一级缓存一样,第一次查询会将数据放到缓存中,然后第二次查询直接去缓存读取。

但是一级缓存是基于 SqlSession 的,二级缓存是基于 mapper 的 namespace 的。

也就是说,多个 SqlSession 可以共享同一个二级缓存区域。如果两个 mapper 的 namespace 相同,那么即使是两个 mapper,这两个 mapper 执行 sql 查询的数据也将保存在相同的二级缓存区域中。


Terwer...大约 3 分钟MyBatis后端开发开源框架二级缓存mybatis
MyBatis的一级缓存

在 MyBatis 中,一级缓存是默认开启的。

通过场景来理解:

场景一

1、在一个 SqlSession 中,对 User 表进行两次根据 ID 的查询,查看发出 sql 语句的情况。

/**
 * 根据ID查询用户
 *
 * @param id
 * @return
 */
@Select("select * from user where id=#{id}")
User findUserById(Integer id);

@Before
public void before() throws Exception {
    System.out.println("before...");
    InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
    //根据 sqlSessionFactory 产生 session
    sqlSession = sqlSessionFactory.openSession();
    // 这样也是可以的,这样的话后面就不用每次都设置了
    // sqlSession = sqlSessionFactory.openSession(true);
    userMapper = sqlSession.getMapper(IUserMapper.class);
}

@Test
public void testFindUserById() {
    //第一次查询,发出sql语句,并将查询出来的结果放进缓存中
    User user = userMapper.findUserById(1);
    System.out.println(user);

    //第二次查询,由于是同一个sqlSession,会在缓存中查询结果 //如果有,则直接从缓存中取出来,不和数据库进行交互
    User user2 = userMapper.findUserById(1);
    System.out.println(user2);
}

Terwer...大约 5 分钟MyBatis后端开发开源框架查询缓存mybatis一级缓存
MyBatis缓存的概念

缓存回顾

缓存就是内存中的数据,常常来自对数据库查询结果的保存。

使用缓存可以避免频繁与数据库交互,进而提高响应速度。

MyBatis 对缓存的支持

MyBatis 也提供了对缓存的支持,分为 一级缓存二级缓存。可以用下面的图来理解:

  1. 一级缓存是 SqlSession 级别的缓存。在操作数据库时,需要构造 SqlSession 对象,在对象中有一个 HashMap 的数据结构用于存储缓存数据。不同的 SqlSession 之间缓存的数据区域(HashMap)是不同的。
  2. 二级缓存是 Mapper 级别的缓存。多个 SqlSession 操作同一个 Mapper 的 sql 语句,多个 SqlSession 可以共用二级缓存,二级缓存是跨 SqlSession 的。

Terwer...大约 1 分钟MyBatis后端开发开源框架缓存二级缓存数据库数据mybatis一级缓存
MyBatis的注解实现复杂映射开发

xml 配置方式实现复杂映射回顾

实现复杂映射我们之前可以在映射文件中通过配置来实现,使用注解开发后,我们可以通过 @Results 注解,@Result 注解,@One 注解和 @Many 注解组合完成复杂关系的配置。

注解 说明
@Results
代替的是标签 <ResultMap>,该注解中可以使用单个的 @Result 注解,也可以使用 @Result 集合。
使用方式:@Results({@Result(), @Result()}) 或者 @Results(@Result())
@Result
代替了 <id> 标签和 <result> 标签
@Result 中的属性介绍
column:数据库中的列名
property:要装配的属性名
one:需要使用 @One 注解( @Result(one=@One)()
many:需要使用 @Many 注解( @Result(many=@many)()
@One(一对一) 代替了 <assocation> 标签,是多表查询的关键,在注解中用来指定子查询返回单一对象。
@One 注解属性介绍
select:指定用来多表查询的 sqlmapper
使用格式:@Result(column="", property="", one=(select=""))
@Many(多对一) 代替了 <collection> 标签,是多表查询的关键,在注解中用来指定子查询返回对象集合。
使用格式:@Result(property="", column="", many=@many(select=""))

Terwer...大约 10 分钟MyBatis后端开发开源框架注解mybatiscomplexframeworkmybatis-14mapping
MyBatis常用注解及基本增删改查的注解实现

MyBatis 的常用注解

注解可以减少 Mapper 文件的编写,常用注解如下;

@Insert:实现新增

@Update:实现更新

@Delete:实现删除

@Select:实现查询

@Result:实现结果集封装

@Results:可以和@Result 一起使用,封装多个结果集

@One:实现一对一结果集封装


Terwer...大约 4 分钟MyBatis后端开发开源框架mybatisannotationframeworkmybatis-13
MyBatis复杂映射开发之多对多查询

多对多查询的模型

用户表和角色表的关系为,一个用户有多个角色,一个角色被多个用户使用。

多对多查询的需求:查询所有用户的同时查询出该用户对应的所有角色。

@startuml

!theme plain
top to bottom direction
skinparam linetype ortho

class sys_role {
   rolename: varchar(255)
   roleDesc: varchar(255)
   id: int(11)
}
class sys_user_role {
   userid: int(11)
   roleid: int(11)
}
class node2 as "user  /* 用户表 */" {
   username: varchar(50)
   password: varchar(50)
   birthday: varchar(50)
   id: int(11)
}

sys_user_role  ^-[#595959,plain]-  sys_role      : "roleid:id"
sys_user_role  ^-[#595959,plain]-  node2         : "userid:id"
@enduml

Terwer...大约 3 分钟MyBatis后端开发开源框架mybatisframework多对多many-to-manymybatis-12
MyBatis复杂映射开发之一对多查询

一对多查询模型

用户和订单表的关系为,一个用户有多个订单,一个订单只能属于一个用户。

一对多查询需求:查询多有用户,与此同时查询用户具有的订单信息。

一对多查询语句

对应的sql语句

select u.*,o.ordertime,o.total,o.uid from user u left join orders o on u.id = o.uid;

Terwer...大约 3 分钟MyBatis后端开发开源框架mybatisframeworkone-to-manymappingmybatis-11
MyBatis复杂映射开发之一对一查询

一对一查询需求

用户表和订单表的关系为:一个用户可以有多个订单,一个订单只能从属于一个用户

一对一查询需求:查询一个订单,同时查询出该订单所对应的用户

对应的sql语句:select * from orders o,user u where o.uid=u.id

查询结果如下:

id ordertime total uid id username password birthday
1 2022-03-17 17:15:33 3000 1 1 lucy 123 2022-03-17 17:15:56
2 2022-03-17 17:15:33 4000 1 1 lucy 123 2022-03-17 17:15:56
3 2022-03-17 17:15:33 5000 2 2 tom 123 2022-03-17 17:15:56

Terwer...大约 3 分钟MyBatis后端开发开源框架frameworkmybatisquerymybatis-10
Mybatis基本流程及配置文件解析

Mybatis基本流程

1、利用Resources工具类加载配置文件,并转换成输入输出流

2、利用解析的配置,创建SqlSessionFactory工厂

3、生产SqlSession

4、SqlSession调用方法

Mybatis配置文件分析

sqlMapConfig.xml

MyBatis核心配置文件层级


Terwer...大约 5 分钟MyBatis后端开发开源框架配置事务mybatisconfigcfgmybatis-9framework
MyBatis的基本使用

快速入门

Mybatis的官网:https://mybatis.org/mybatis-3/

MyBatis的开发步骤

添加MyBatis的坐标

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.encoding>UTF-8</maven.compiler.encoding>
    <java.version>1.8</java.version>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
</properties>

<dependencies>
    <!--mybatis坐标-->
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>3.4.5</version>
    </dependency>
    <!--mysql驱动坐标-->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.6</version>
        <scope>runtime</scope>
    </dependency>
    <!--单元测试坐标-->
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
        <scope>test</scope>
    </dependency>
    <!--⽇志坐标-->
    <dependency>
        <groupId>log4j</groupId>
        <artifactId>log4j</artifactId>
        <version>1.2.12</version>
    </dependency>
</dependencies>

Terwer...大约 5 分钟MyBatis后端开发开源框架mybatisbasicuseframeworkmybatis-8
2
3