mybatis相关问题


mybatis相关

一级缓存

一级缓存是sqlSession级别的,每一次操作数据库的时候都会构造一个sqlSession对象,所以不同的操作sqlSession是不同的,也是互相不想影响的
当在同一个sqlSession内执行两次重复的sql的时候,第一次查询的数据会被写入缓存中(一个HashMap存在内存中),而第二次相同查询的时候会直接从缓存中取出缓存数据
提高查询效率

但当sqlSession执行DML操作时候,就会清空缓存,下次查询就会从数据库查询再写入缓存中,避免出现脏读现象,且当sqlSession结束时,缓存也会消失

二级缓存

二级缓存默认是不开启的,需要手动配置(mapper.xml)

<cache/ >

默认属性如下 :

    映射语句文件中的所有 select 语句将会被缓存。
    映射语句文件中的所有 insert,update 和 delete 语句会刷新缓存。
    缓存会使用 Least Recently Used(LRU,最近最少使用的)算法来收回。
    根据时间表(比如 no Flush Interval,没有刷新间隔), 缓存不会以任何时间顺序来刷新。
    缓存会存储列表集合或对象(无论查询方法返回什么)的 1024 个引用。
    缓存会被视为是 read/write(可读/可写)的缓存,意味着对象检索不是共享的,而且可以安全地被调用者修改,而不干扰其他调用者或线程所做的潜在修改。

也可以自定义二级缓存

  eviction:缓存回收策略
  - LRU:最少使用原则,移除最长时间不使用的对象
  - FIFO:先进先出原则,按照对象进入缓存顺序进行回收
  - SOFT:软引用,移除基于垃圾回收器状态和软引用规则的对象
  - WEAK:弱引用,更积极的移除移除基于垃圾回收器状态和弱引用规则的对象
  flushInterval:刷新时间间隔,单位为毫秒,这里配置的100毫秒。如果不配置,那么只有在进行数据库修改操作才会被动刷新缓存区
  size:引用额数目,代表缓存最多可以存储的对象个数
  readOnly:是否只读,如果为true,则所有相同的sql语句返回的是同一个对象(有助于提高性能,但并发操作同一条数据时,可能不安全),如果设置为false,则相同的sql,后面访问的是cache的clone副本。

二级缓存的作用于是整个mapper,比sqlSession的作用域更大,多个sqlSession可以共享一个mapper,当多个sqlSession操作同一个mapper下的sql语句
且参数也相同,在第一个sqlSession查询之后,会将一级缓存升级为二级缓存,下次任意sqlSession执行当前mapper同样的sql且参数相同,会直接从二级缓存中拿数据

同样DML操作是,也会清空缓存



ps:( 多表操作不能使用二级缓存,这样会导致数据不一致的问题)

延迟加载

将采用高级映射(resultMap)实现多表联查时向数据库发出的SQL语句拆分成若干条单表查询的SQL语句,当需要返回数据时才会向数据库发出只针对当前数据的SQL语句,提高查询效率。

也需要手动配置

<!--全局参数设置-->
<settings>
    <!--延迟加载总开关-->
    <setting name="lazyLoadingEnabled" value="true"/>
    <!--侵入式延迟加载开关-->
    <!--3.4.1版本之前默认是true,之后默认是false-->
    <setting name="aggressiveLazyLoading" value="true"/>
</settings>

举个栗子

  <!--根据team的id查找player-->
  <select id="selectPlayerByTeamId" resultType="Player">
      select id,name from t_player WHERE tid=#{id}
  </select>
  
  
  <!--集合的数据来自select查询,该查询的条件是selectTeamByIdAlone查询出的id-->
  <resultMap id="teamMapAlone" type="Team">
      <id column="id" property="id"/>
      <result column="name" property="name"/>  //playerList为entity的一个字段 内容为整条sql的查询结果
      <collection property="playerList" ofType="Player" select="selectPlayerByTeamId" column="id"/>
  </resultMap>
  
  
  <select id="selectTeamByIdAlone" resultMap="teamMapAlone">
      SELECT id,name FROM t_team where id=#{id}
  </select>

MyBatis接口和XML的映射

首先mapper接口名和xml的namespace一样是肯定知道的
实现方法主要是根据JDK动态代理来实现,mybatis讲我们设置好的扫描包路径下的接口解析成代理工厂对象(MapperProxyFactory )
之后创建接口代理类,然后判断namespace是否有同名,然后生成接口动态代理类,执行invoke方法,再执行execute执行语句

后记

比较拙劣

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值