栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

【学习笔记】Mybatis框架学习及个人感悟

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

【学习笔记】Mybatis框架学习及个人感悟

文章目录
  • 一、简介
    • 1.1、什么是Mybatis
    • 1.2、持久化
    • 1.3、为什么需要Mybatis
  • 二、第一个Mybatis程序
    • 2.1、搭建环境
    • 2.2、创建一个子模块
    • 2.3、编写代码
    • 2.4、测试
    • 2.5、小结
  • 三、CRUD
    • 3.1、Mybatis传递多个参数(万能的Map)
  • 四、配置解析
    • 4.1、核心配置文件
    • 4.2、环境变量(environments)
    • 4.3、属性
    • 4.4、类型别名(typeAliases)
    • 4.5、设置
    • 4.6、映射器(mappers)
    • 4.7、其他
  • 五、生命周期和作用域
    • 5.1、SqlSessionFactoryBuilder
    • 5.2、SqlSessionFactory
    • 5.3、SqlSession
    • 5.4、Mybatis三大对象映像图
  • 六、解决属性名和字段名不一致问题
    • 6.1、解决方法一:取别名(数据库层面)
    • 6.2、解决方式二:结果映射resultMap(Java层面,重点)
    • 6.3、用例子明白resultMap底层是反射执行
  • 七、日志
    • 理解打包后的项目经历了什么
  • 八、分页
    • 7.1、使用Limit分页
  • 九、使用注解开发
    • 9.1、面向接口编程
    • 9.2、使用注解开发
    • 9.3、CRUD
    • 9.4、Lombok
  • 十、多对一(association)
    • 解法一:按照结果嵌套查询(连表查询,重要需掌握)
    • 解法二:按照查询嵌套处理(子查询,复杂不建议)
  • 十一、一对多(collection)
    • 小结
  • 十二、动态SQL
    • 动态SQL之我见
  • 十三、缓存
    • Mybatis缓存
    • Mybatis一级缓存
    • Mybatis二级缓存
    • 自定义缓存
    • 缓存之我见

Mybatis
所需环境回顾
JDK1.8JDBC
Mysql5.7/8.0Mysql
maven3.6.1Maven
IDEAJunit

SSM(Spring + SpringMvc + Mybatis)框架:配置文件相关的。学习的最好方式:官方文档。

一、简介 1.1、什么是Mybatis

  • MyBatis 是一款优秀的持久层框架。
  • 它支持自定义 SQL、存储过程以及高级映射。
  • MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。
  • MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。
  • MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis 。2013年11月迁移到Github

获得Mybatis

  • maven仓库

    org.mybatis
    mybatis
    3.5.2

  • 中文文档:https://mybatis.org/mybatis-3/zh/index.html Mybatis学习最重要的文档。
  • Github:https://github.com/mybatis/mybatis-3/releases
1.2、持久化

数据持久化

  • 持久化就是将程序的数据在持久状态(硬盘/外存中)和瞬时状态(内存中)转化的过程

  • 内存(Random Access Memory,RAM):断电即失

  在大学里面看过一本关于早期工业革命历史的书,学习到有个叫继电器的器件,早期内存核心就是继电器,具体构造是个弹片,随着电位信息拨动(挨上就是1,没挨上就是0,这也就是为什么计算器底层是二进制的又一证据),这个继电器的电位信息来自于地址总线(几根就是我们说的32/64操作系统,说的就是内存大小),因为直接由地址总线控制,所以能直接定位(Access)某个位置,这也就是为什么内存速度快。同时内存核心元件是继电器,一旦断电,继电器拨片会立马回弹,导致回到初始状态,即数据都变成000000序列了,数据就不复存在了。这就是RAM存储器的特性,速度快,怕断电。在计算机中充当着内存的角色。毕竟是课外学习到的知识,也不是科班,所以可能有误,望高人指出。

  • 数据库(JDBC), io文件持久化。

  本质上都是放在外存上。学习的课外知识。分为固态硬盘和机械硬盘。机械硬盘,你可以看作小时候看的碟机的CD运行原理,有一个小小的指针放在上面随着转动这就是再读取了。所以机械硬盘怕摔,针头偏移了的话,没咬合住就读取不了了。固态硬盘,半导体技术,懵逼,不懂,只知道他有个专业术语是颗粒。

为什么要持久化

  • 假如做一个学生信息管理系统,我们从view层获得一个学生信息,一个老师早上忙活大半天录了300个学生,中午吃饭去电脑断电,在内存(RAM)中的数据,断电丢失,全部没有了,白忙活一场。所以我们要把它转到外存去,长期保存,转移到数据库里,看表容易多了。
  • 内存太贵了

持久层:Dao层,Service层,Controller层。

  • 完成持久化工作的代码块
  • 层界线十分明显
1.3、为什么需要Mybatis
  • 方便帮助程序员将数据存入到数据库中
  • 传统的JDBC代码太复杂了,简化,框架,自动化。
  • 不用Mybatis也可以,学了更容易上手。技术没有高低之分。
  • 优点
    • 简单易学
    • 灵活
    • sql和代码的分离,提高了可维护性。
    • 提供映射标签,支持对象与数据库的orm字段关系映射
    • 提供对象关系映射标签,支持对象关系组建维护
    • 提供xml标签,支持编写动态sql。

总结及自己的思考

  Mybatis框架完全可以不学,你可以用更加全自动的Hibernate框架。Hibernate全自动框架,Mybatis半自动框架。理解就在于hibernate将sql语句都内部处理了(黑箱操作),用户使用时只需调用相关api即可。而mybatis还需自己写sql语句,这样更加灵活。因为不同的需求可能需要不同程度的sql语句,sql这种变化大的由外面来写最好。

  还是那句话,框架没有好坏之分,但现在主流的方向就是这个,所以为了迎合,必须要学。

  同时,对于框架,我只想说,不用太放在心上,刨根问题,就是人家为我们做好的工具,你可以拿来使用,只不过要学习人家规定的语法/配置文件。你完全可以给一个不懂底层实现的人让他去学框架的使用,使用框架使得开发越来越快。框架就是人家定好的规则,你去学习使用完成自己的目标,做一个API的调用者,很简单;但要做一个框架的开发者(工具的建造者),很难。所以学习框架就是个上山和下山的过程,上山学习如何快速使用,下山,刨根问题,去探究人家这个功能是怎么实现的。深度和广度的问题,取决在于你。

二、第一个Mybatis程序

思路:搭建环境–>导入Mybatis–>编写代码–>测试

2.1、搭建环境

搭建数据库

CREATE DATAbase `mybatis`;

USE mybatis;

CREATE TABLE `user`(
  `id` INT(20) NOT NULL,
  `name` VARCHAR(30) DEFAULT NULL,
  `pwd` VARCHAR(30) DEFAULT NULL,
  PRIMARY KEY(`id`)
)ENGINE=INNODB DEFAULT CHARSET=utf8;

INSERT INTO `user` (`id`,`name`,`pwd`) VALUES
(1,'狂神','123456'),
(2,'张三','456852'),
(3,'李四','qwertyuiop');

新建项目

  1. 新建一个普通的maven项目

  2. 删除src目录(使用父工程子项目模式来做,为了一呼百应)

  3. 父工程pom.xml导入maven依赖

    
        
            mysql
            mysql-connector-java
            8.0.26
        
        
            org.mybatis
            mybatis
            3.5.2
        
        
            junit
            junit
            4.12
            test
        
    
2.2、创建一个子模块

创建一个子模块,该子模块也是maven的普通项目。

  • 编写mybatis的核心配置文件

在子模块的resource目录(web学习中明白打包导出后直接就在当前目录下)下编写mybatis-config.xml(官方建议这样命名)。




    
        
            
            
                
                
                
                
            
        
    


该配置文件不要写中文注释(硬要写UTF-8改为UTF8/GBK)!

&代替&

  • 编写mybatis工具类
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 MybatisUtil {
    private static SqlSessionFactory sqlSessionFactory;

    static {
        try {
            //使用MybatisUtils第一步:获取sqlSessionFactory对象
            String resource = "mybatis-config.xml";
            InputStream resourceAsStream = Resources.getResourceAsStream(resource);
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    //既然有了 SqlSessionFactory,顾名思义,我们可以从中获得 SqlSession 的实例。
    // SqlSession 提供了在数据库执行 SQL 命令所需的所有方法。
    public static SqlSession getSqlSession() {
        return sqlSessionFactory.openSession();
    }
}
2.3、编写代码
  • 实体类pojo

写在对应包下,与数据库表一一对应。

public class UserModel {
    private int id;
    private String name;
    private String pwd;
 
    //get,set,toString来一套
}
  • DAO接口
public interface IUserDao {
    List getUserList();
}
  • 接口实现类由原来的UserDaoImpl转变为一个Mapper配置文件





    
    SELECT * FROM mybatis.`user`
  

右边感叹警告,未配置数据库。配置Mysql,方便快速查询相应表和字段。

  • 去mybatis的核心配置文件进行配置
	
        
    

因为此时要访问的是一个目录下的xml文件,而不是类文件,所以要用/,而不用.。

2.4、测试

junit测试,应该去test目录下进行。所以要在test目录下建立和src一样的包结构。

import com.kuang.pojo.UserModel;
import com.kuang.util.MybatisUtil;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

import java.util.List;

public class userDaoTest {
    @Test
    public void userDaoTest() {
        //第一步:获得SqlSession对象
        SqlSession sqlSession = MybatisUtil.getSqlSession();
        //执行
        IUserDao userDao = sqlSession.getMapper(IUserDao.class);

        List userList = userDao.getUserList();
        for (UserModel userModel : userList) {
            System.out.println(userModel);
        }
        sqlSession.close();
    }
}

可能遇到的问题

  1. 配置文件没有注册

要去mybatis的核心配置文件下进行相关xml文件的注册绑定

  1. 绑定接口错误(namespace)
  2. 方法名不对(id)
  3. 返回类型不对(resultType)

  1. Maven导出资源问题

Mybatis为了增加关联性,我们经常把xml文件等配置文件和类放在一起。但是默认导入包不会导出src下的配置文件。所以在父工程下的pom.xml下加过滤器。

为了关联性:

为了不被过滤,所以需要在pom.xml添加

    
        
            
                src/main/resources
                
                    ***.xml
                
                false
            
            
                src/main/java
                
                    ***.xml
                
                false
            
        
    
2.5、小结

  Mybatis就是把我们以前写userDaoImple实现类做法转成了写一个xml文件的做法。让我们以前写的好多代码(connection、preparestatment等)得到简化。

演化过程

以前做法Mybatis做法
implements 接口namespace = “包权限接口名”
实现接口方法id=“接口方法名”
返回值resultType = “带包权限类名”

  Mybatis就是把实现类变为写一个xml标签,其标签体专注SQL语句。写完该xml,记得要去mybatis的核心配置文件进行注册。namespace是绑定,去核心配置文件添加叫注册

三、CRUD
  • id:就是对应的namespace中的方法名;
  • resultType:SQL语句的返回值!
  • parameterType:参数类型。

有了Mybatis以后的CRUD步骤都是一致的。

编写接口—>编写接口对应的mappeer.xml中的sql语句—>测试(固定四步,打开sqlSession;获取sqlSession.getMapper(接口.class);进行相关操作;最后关闭sqlSession)

Select

选择,查询语句;

  1. 编写接口
    //名字命名起的越底层,高层越方便调用以达到复用,DAO和Service想成两个人之间的对话
    UserModel getUserRecordById(int id);
  1. 编写对应的mappeer中的sql语句
    
        select s.id as sid,s.name as sname,s.teacher_id as tid,t.name as tname
        from student as s,teacher as t where s.teacher_id = t.id
    

    
        
        
        
        
        
            
            
        
    
    

这里最重要的就是写SQL语句了,在这我也彻底明白了SQL语句,下面总结下。

select语句主体

SELECT (查出来形成新表的列名,强烈建议用as写好新表的列名) FROM (从哪几张表,建议也用as起别名,方便区分是哪一个表的列) WHERe (条件,不加就会变成笛卡尔积的形式)

写Select语句就先写主体,SELECT … FROM … WHERe,然后根据需求去填充。(别名用as明示,别只写个空格)

select s.id as sid,s.name as sname,s.teacher_id as tid,t.name as tname
from student as s,teacher as t where s.teacher_id = t.id

联表查询的SQL语句就很好写和分析了。上面的SQL语句代表从student表(别名为s)和teacher表(别名为t),形成结果新表sid列是student表的id;新表sname列是student表的name;新表tid列是student表的teacher_id;新表tname是teacher表的name;条件为student表的teacher_id与teacher表的id相等。

起别名的原因是:经过select查询形成的新表的新列名就是按照别名走的,如果没设置就按源表走;同时设置了别名,mybtatis写参数也就按照新表走了。

在mybatis核心配置XML文件进行注册

    
        
    

测试,成功。

解法二:按照查询嵌套处理(子查询,复杂不建议)
  1. 查询所有学生的信息
  2. 根据查询出来的学生的tid,寻找对应的老师! 子查询

StudentDaoMapper.xml

    
        select * from teacher where id = #{id}
    

在mybatis核心配置XML文件进行注册;测试,也成功。

但还是建议使用连表查询,构造SQL简单且易懂。

连表查询构建的SQL直接可以在数据库的控制台进行输入,然后看结果,而子查询不行,子查询还牵扯参数传递,所以复杂不好理解和调试。

十一、一对多(collection)

比如:一个老师拥有多个学生!

对于老师而言,就是一对多的关系

实体类

public class TeacherModel {
    private int id;
    private String name;
    private List studentList;
}

接口

public interface ITeacherDao {

    TeacherModel getTeacherById(@Param("teacherId") int id);
}

建立接口的实现XML文件

TeacherDaoMapper.xml



    
    select *
    from mybatis.blog where 1=1
    
        and title = #{title}
    
    
        and author = #{author}
    


where 1 = 1这个是为了where语句必须出现,但不知道后面是否满足条件。因此写个1 = 1。1=1 永真, 1<>1 永假。where 1<>1 这句查询出来的是 只要表结构不要表数据。

choose (when, otherwise)形如switch语句



这里没有再使用where 1 = 1了,而使用了where标签。where标签,可以让SQL字符串拼接正确。

有了where标签就不建议使用where 1=1了。where 1=1会导致表中的数据索引失效。

所谓的动态SQL,本质还是SQL语句,只是可以在SQL层面,去执行一个逻辑代码

SQL片段和foreach操作就不涉及了。

动态SQL之我见

怎么说呢,我认为理解并且会写最简单if就行了,动态SQL就是在拼接SQL字符串,mybatis就是操作数据库的框架,按照分离原则,数据库只管数据库的操作,少引入逻辑操作,引入个if就不错了。没有动态SQL,你可以一直划分细颗粒度的DAO操作,写的越简单越基础的方法,粒度越小,复用性越高,可以称为元操作吧。

十三、缓存

  缓存(Cache,kashi,以前一直读错kachi纠正),这是一个很重要的概念。缓存对mybatis优化很起作用,缓存说白了就是提高查询效率。

  最开始,单服务器,少量用户向服务器进行请求资源,服务器只负责和客户连接,资源文件肯定不存在服务器上,而放在数据库上,服务器分析客户的请求,然后从数据库取得相关数据再返还,早期就是这样的单线;

  而随着网络越来越发达,用户数量激增,传统的单个服务器承受不了巨大的压力,因此就需要多个服务器来进行处理,这些服务器可以跨地域设置以满足不同地区用户的体验感,快速响应用户请求。

  虽说请求由于多个服务器所以处理速度快了,但是真正的资源要去数据库拿;而数据库其本质也是个服务器,其最主要工作就是读和写。压力有都转移到数据库这里了。应该怎么办呢?架构中没有什么是加一层解决不了的,分析读操作和写操作应该是独立的,所以加一层memoryCache缓存,memoryCache存储常用的数据库资源,实现读写分离,读操作先读memoryCache读,没有再去数据库读,而写的压力全给数据库。

  如果还嫌处理速度不够快,那么就把数据库也弄成多个,这样可以分担压力。但是多个数据库就要考虑数据一致性的问题了。如何保证呢?主从复制!

从上面发展历史中,你也就能明白缓存就是一个存放常用数据的仓库(池子),方便用户快速得到。

Mybatis中的缓存也是如此意思

1.什么是缓存[ Cache ]

  • 存在内存中的临时数据。
  • 将用户经常查询的数据放在缓存(内存)中,用户去查询数据就不用从磁盘上(关系型数据库数据文件)查询,从缓存中查询,从而提高查询效率,解决了高并发系统的性能问题。

2.为什么使用缓存?

  • 减少和数据库的交互次数,减少系统开销,提高系统效率。

3.什么样的数据能使用缓存?

  • 经常查询并且不经常改变的数据。
Mybatis缓存
  • MyBatis包含一个非常强大的查询缓存特性,它可以非常方便地定制和配置缓存。缓存可以极大的提升查询效率。
  • MyBatis系统中默认定义了两级缓存:一级缓存和二级缓存
    • 默认情况下,只有一级缓存开启。(SqlSession级别的缓存,也称为本地缓存)。二级缓存需要手动开启和配置,他是基于namespace(一个接口的mapper.xml)级别的缓存。
    • 为了提高扩展性,MyBatis定义了缓存接口Cache。我们可以通过实现Cache接口来自定义二级缓存
Mybatis一级缓存

mybatis一级缓存又称本地缓存。

  • 一级缓存默认打开

  • 一级缓存生命周期是一次会话(一次打开和关闭sqlSession),此会话期间有效

    public void test() {
        SqlSession sqlSeeion = MybatisUtil.getSqlSeeion();  //openSession

        //一级缓存仅在此之间有效

        sqlSeeion.commit();
        sqlSeeion.close();
    }

(1)与数据库同一次会话期间查询到的数据会放在本地缓存中。

(2)以后如果需要获取相同的数据,直接从缓存中拿,没必须再去查询数据库;

  • 例子证明一级缓存存在
    @Test
    public void test() {
        SqlSession sqlSeeion = MybatisUtil.getSqlSeeion();

        IUserDaoFive mapper = sqlSeeion.getMapper(IUserDaoFive.class);
        UserModelFive user = mapper.getUserById(1);

        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        UserModelFive anotherUser = mapper.getUserById(1);

        System.out.println("他俩地址值相同吗?" + (user == anotherUser));    //true

        sqlSeeion.commit();
        sqlSeeion.close();
    }

输出为true,查询同一个id,一开始我以为底层肯定是使用反射机制new了一个新的pojo对象,而此时==为true,说明地址值相同,就说明此时这两个对象是一样的,这就证明了一级缓存的存在。同时日志信息可以看到相关SQL只执行了一次,说明第二次对象就是从一级缓存取的。

  • 一级缓存失效的情况

(1)增删改(insert,update,delete)操作,可能会改变原来的数据,为了确保数据实时,所以会刷新一级缓存

(2)查询不同的Mapper.xml(也就是说查了另一个接口的实现XML文件,从这知道同一个sqlsession下的不同mapper的缓存是各自的,后证实为不同的mapper.xml对应不同的二级缓存,后面学到可以mapper.xml通过引用传递二级缓存)

    @Test
    public void testMapperOneCache() {
        SqlSession sqlSeeion = MybatisUtil.getSqlSeeion();

        IUserDaoFive mapperOne = sqlSeeion.getMapper(IUserDaoFive.class);
        UserModelFive userOne = mapperOne.getUserById(1);

        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        IUserDaoSix mapperTwo = sqlSeeion.getMapper(IUserDaoSix.class);
        UserModelFive userTwo = mapperTwo.getUserByUserId(1);


        System.out.println("地址值相同吗?" + (userOne == userTwo));
        //false。说明不同的mapper.xml有自己不同的一级缓存(后证实为不同的mapper.xml对应不同的二级缓存)

        sqlSeeion.commit();
        sqlSeeion.close();
    }

(3)手动清理缓存

sqlSeeion.clearCache();
Mybatis二级缓存
  • 二级缓存也叫全局缓存,一级缓存作用域太低了(一次sqlseesion完就关闭),所以诞生了二级缓存
  • 基于namespace级别的缓存,一个名称空间,一个mapper.xml对应一个二级缓存;
  • 工作机制
    • 一个会话查询一条数据,这个数据就会被放在当前会话的一级缓存中;
    • 如果当前会话关闭了,这个会话对应的一级缓存就没了;但是我们想要的是,会话关闭了,一级缓存中的数据被保存到二级缓存中;
    • 新的会话查询信息,就可以从二级缓存中获取内容;
    • 不同的mapper查出的数据会放在自己对应的缓存(map)中;

使用步骤

  • 前提条件一:在核心配置文件显示的开启全局缓存
    
        
        
    
  • 前提条件二:在当前Mapper.xml中使用二级缓存开启
    
    
    
  • 所有的数据都会先放在一级缓存中,只有会话提交(sqlSeeion.commit()),或者关闭(sqlSeeion.close())的时候,才会转存到二级缓存中!

  • 开启上面两个条件后,二级缓存就生效了。当一级缓存关闭(sqlsession进行close后)时,同一mapper.xml下查询的对象会放在二级缓存中;不同的mapper.xml有自己独有的二级缓存。

    @Test
    public void testTwoCache() {
        SqlSession sqlSeeion = MybatisUtil.getSqlSeeion();

        IUserDaoFive mapper = sqlSeeion.getMapper(IUserDaoFive.class);
        UserModelFive user = mapper.getUserById(1);
        sqlSeeion.commit();
        sqlSeeion.close();


        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        SqlSession sqlSeeion1 = MybatisUtil.getSqlSeeion();

        IUserDaoFive mapper1 = sqlSeeion1.getMapper(IUserDaoFive.class);
        UserModelFive user1 = mapper1.getUserById(1);

        sqlSeeion1.commit();
        sqlSeeion1.close();


        System.out.println("地址值相同吗?" + (user == user1));
        //true
        //1.核心文件开启显示开启缓存    
        //2.mapper.xml定义缓存   
        //cache没有readonly="true",会报未序列化异常,和流有关系
    }

  • 不同mapper.xml引用别的mapper.xml的缓存
    @Test
    public void testMapperMoveStore() {

        SqlSession sqlSeeion = MybatisUtil.getSqlSeeion();

        IUserDaoFive mapper = sqlSeeion.getMapper(IUserDaoFive.class);
        UserModelFive user = mapper.getUserById(1);

        sqlSeeion.commit();
        sqlSeeion.close();


        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        SqlSession sqlSeeion1 = MybatisUtil.getSqlSeeion();

        IUserDaoSix mapper1 = sqlSeeion1.getMapper(IUserDaoSix.class);
        UserModelFive user1 = mapper1.getUserByUserId(1);

        sqlSeeion1.commit();
        sqlSeeion1.close();

        System.out.println("不同mapper的二级缓存可以引用吗?" + (user == user1));
        //true。探究过程很有意思
    }
     
    

这里试了半天都是false,心态都崩了,和官方文档说的cache-ref不一样啊。在崩溃之际,网上搜索资料,终于解开谜题。参考了这位大佬的博文cache-ref。从中明白了cache是一个实例对象,不能既引入,还引入<cache-ref/>;解析结点,Mapper为自己创建一个缓存实例不再引用<cache-ref/>的缓存实例;也就是说一个mapper要么定义自己的二级缓存,要么引用别人的二级缓存,只能用一个池子。

缓存原理映像图

自定义缓存

当然可以使用自己自定义的缓存,我们先来看org.apache.ibatis.cache.Cache接口。

package org.apache.ibatis.cache;

import java.util.concurrent.locks.ReadWriteLock;

public interface Cache {

  String getId();

  void putObject(Object key, Object value);

  Object getObject(Object key);

  Object removeObject(Object key);

  void clear();

  int getSize();

  default ReadWriteLock getReadWriteLock() {
    return null;
  }

}

你要实现自定义缓存就要实现该接口,完成其规定的所有方法。

从这里明白了。实际上,设计一个接口,提出这些方法就是设计一种策略!规定你必须完成什么,后面的实现该接口的实现类是策略的具体实现了。

然后相关mapper.xml导入自定义缓存就行了


工作一般在Redis(已经做到极致了)数据库来做缓存! K-V键值对的形式。都以K-V存储,直接取,直接放。这个我们到后面再学习。

缓存之我见

缓存落到最后都是为了提高查询效率。

一级缓存其作用域就是随着sqlSeesion生死,仅在同一个sqlSession包裹下有效,不同的sqlSession有自己不同的一级缓存。

二级缓存前提条件需要进行核心配置文件的显示开启,还需要在mapper.xml下开启cache标签。所有的数据都会先放在一级缓存中,只有会话提交(sqlSeeion.commit()),或者关闭(sqlSeeion.close())的时候,才会转存到二级缓存中!二级缓存的作用域就是一个mapper.xml下的,不同的mapper.xml有自己不同的二级缓存。随着一级缓存的关闭,相同mapper.xml查询的对象就会转存到同一个二级缓存下,不同mapper.xml查询到的对象会放在不同的二级缓存下。不同的mapper.xml要么使用自己的二级缓存池,要么引用别的mapper.xml的二级缓存池。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/270599.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号