MyBatis原理

MyBatis原理

原理

  • MyBatis启动时,解析mybatis的配置文件,并且从指定路径下解析mapper.xml配置文件
    • 把每条sql语句映射成MappedStatement
  • 然后把MappedStatement存放到Configuration的一个mappedStatements属性中(mappedStatements是一个HashMap),key为namespace + id,value为MappedStatement
  • 当要执行sql语句的时候,从mappedStatements这个map中通过id找到MappedStatement
  • 获取MappedStatement对应sql语句、查询参数
  • 查看一级缓存中有没有数据,有则直接返回
  • 缓存没有数据,则查询数据库
    • 通过调用原生的jdbc方法,执行sql语句,获取到结果,删除旧缓存
  • 把结果放到一级缓存,返回结果

接口方式

思考一个问题,通常的Mapper接口,我们可以不实现方法,却可以使用。这是为什么呢?答案很简单 动态代理

开始之前介绍一下MyBatis初始化时对接口的处理:

  • 当判断解析到接口时,会创建此接口对应的MapperProxyFactory对象,存入HashMap中,key = 接口的class对象,value = 此接口对应的MapperProxyFactory对象。
  • 当执行sql的时候,通过MapperProxyFactory生成动态代理实例(JDK动态代理)
  • 通过代理实例,将请求转发给invoker方法
  • 在invoke()方法中,最终SqlSession中的方法执行sql语句

MyBatis缓存

背景

一次数据库会话中,可能会执行的重复的查询语句,极短时间内重复查询,结果往往是一样的,但是造成了数据库资源的浪费。

为了解决这个问题,MyBatis使用了一级缓存。MyBatis在sqlSession对象(表示会话的对象)中建立了一个简单的缓存,将每次查询的结果缓存起来。如果下次有完全一样的查询,直接返回结果。

一级缓存

特点

  • 一级缓存默认是开启的

  • 作用域是session级别,每个sqlSession各自拥有一级缓存,各自隔离。

  • 第一次查询结果换以key value的形式存起来,如果有相同的key进来,直接返回value,这样有助于减轻数据库的压力。

  • 缓存的key格式如下:

    • cache key: id + sql + limit + offset 
      
  • 当commit或者rollback的时候会清除缓存,并且当执行insert、update、delete的时候也会清除缓存。

二级缓存

特点

  • 一个namespace(mapper.xml)就会有一个缓存
  • 不同的sqlSession之间的二级缓存是共享的
  • 实现二级缓存的时候,MyBatis要求返回的POJO必须是可序列化的,也就是要求实现Serializable接口
    • 因为二级缓存的数据不一定都是存储到内存中,它的存储介质多种多样
    • 如果存储在内存中的话,实测不序列化也可以的。
  • 一般为了避免出现脏数据,所以我们可以在每一次的insert | update | delete操作后都进行缓存刷新
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值