今天面试深圳一家公司的时候,被问到mybatis缓存,当时回到是只知道一级缓存和二级缓存,现在整理一下。

MyBatis 是一个开源、轻量级的数据持久化框架,是 JDBC 和 Hibernate 的替代方案。MyBatis 内部封装了 JDBC,简化了加载驱动、创建连接、创建 statement 等繁杂的过程,开发者只需要关注 SQL 语句本身。MyBatis 支持定制化 SQL、存储过程以及高级映射,可以在实体类和 SQL 语句之间建立映射关系,是一种半自动化的 ORM 实现。其封装性低于 Hibernate,但性能优秀、小巧、简单易学、应用广泛。MyBatis 的主要思想是将程序中的大量 SQL 语句剥离出来,使用 XML 文件或注解的方式实现 SQL 的灵活配置,将 SQL 语句与程序代码分离,在不修改程序代码的情况下,直接在配置文件中修改 SQL 语句。MyBatis 与其它持久性框架最大的不同是,MyBatis 强调使用 SQL,而其它框架(例如 Hibernate)通常使用自定义查询语言,即 HQL(Hibernate查询语言)或 EJB QL(Enterprise JavaBeans查询语言)。

优点

  • MyBatis 是免费且开源的。
  • 与 JDBC 相比,减少了 50% 以上的代码量。
  • MyBatis 是最简单的持久化框架,小巧并且简单易学。
  • MyBatis 相当灵活,不会对应用程序或者数据库的现有设计强加任何影响,SQL 写在 XML 中,和程序逻辑代码分离,降低耦合度,便于同一管理和优化,提高了代码的可重用性。
  • 提供 XML 标签,支持编写动态 SQL 语句。
  • 提供映射标签,支持对象与数据库的 ORM 字段关系映射。
  • 支持存储过程。MyBatis 以存储过程的形式封装 SQL,可以将业务逻辑保留在数据库之外,增强应用程序的可移植性、更易于部署和测试。

缺点

  • 编写 SQL 语句工作量较大,对开发人员编写 SQL 语句的功底有一定要求。
  • SQL 语句依赖于数据库,导致数据库移植性差,不能随意更换数据库。

使用场景

MyBatis 专注于 SQL 本身,是一个足够灵活的 DAO 层解决方案。适用于性能要求高,且需求变化较多的项目,如互联网项目。

拓展

Mybatis-Plus(简称 MP)是 Mybatis 的增强工具,在 Mybatis 的基础上只做增强不做改变,支持 Mybatis 所有原生的特性,为简化开发、提高效率而生。

所谓缓存,就是可以将数据保存在内存中,是互联网系统经常用到的,目前流行的缓存服务器有MongoDB、Redis、Ehcache等,缓存是在计算机内存上保存的数据,读取时无需再从磁盘读入,因此具备快速读取和使用的特点,和大多数持久化框架一样,MyBatis提供了一级缓存和二级缓存的支持,默认情况下,MyBatis只开启一级缓存。

1、一级缓存

一级缓存是基于PerpetualCache(Mybatis自带)的HashMap本地缓存,作用范围为session域内。当session flush(刷新)或close(关闭)之后,该session中所有的cache(缓存)就会被清空。

在参数和SQL完全一样的情况下,我们使用同一个SqlSession对象调用同一个mapper方法,往往只执行一次SQL,因为使用SqlSession第一次查询后,MyBatis会将其放在缓存中,再次查询时,如果没有刷新,并且缓存没有超时的情况下,SqlSession会取出当前缓存的数据,而不会再次发送SQL到数据库,由于SqlSession是相互隔离的,所以如果你使用不同的SqlSession对象,即使调用相同的Mapper、参数和方法,MyBatis还是会再次发送SQL到数据库执行,返回结果。

2、二级缓存

二级缓存是全局缓存,作用域超出session范围之外,可以被所有SqlSession共享。一级缓存缓存的是 SQL 语句,二级缓存缓存的是结果对象。

1)MyBatis 的全局缓存配置需要在 mybatis-config.xml 的 settings 元素中设置,代码如下。

  • <settings>
  • <setting name="cacheEnabled" value="true" />
  • </settings>

2)在 mapper 文件(如 WebMapper.xml)中设置缓存,默认不开启缓存。需要注意的是,二级缓存的作用域是针对 mapper 的 namescape 而言,即只有再次在 namescape 内(net.biancheng.WebsiteMapper)的查询才能共享这个缓存,代码如下。

  • <mapper namescape="net.biancheng.WebsiteMapper">
  • <!-- cache配置 -->
  • <cache
  • eviction="FIFO"
  • flushInterval="60000"
  • size="512"
  • readOnly="true" />
  • ...
  • </mapper>

对于 MyBatis 缓存仅作了解即可,因为面对一定规模的数据量,内置的 Cache 方式就派不上用场了,并且对查询结果集做缓存并不是 MyBatis 所擅长的,它专心做的应该是 SQL 映射。对于缓存,采用 OSCache、Memcached 等专门的缓存服务器来做更为合理。

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐