MyBatis缓存
MyBatis的缓存用于存储查询结果,以便在后续相同查询的情况下避免重复查询数据库,提高性能。
MyBatis的缓存分为两种类型:一级缓存(Local Cache)和二级缓存(Second-Level Cache)。
如下图所示:
MyBatis一级缓存
MyBatis的一级缓存(Local Cache)是一个在SqlSession(数据库会话)级别的缓存,用于存储在当前SqlSession中执行的查询结果。
当查询数据时,查询结果会被缓存在一级缓存中。
如下图所示:
一级缓存特点和行为:
- SqlSession级别:一级缓存是在SqlSession的生命周期内有效,每个SqlSession都有自己独立的一级缓存,不同SqlSession之间的缓存数据不共享。
- 自动开启:MyBatis默认开启一级缓存,无需额外配置,一级缓存在SqlSession创建时自动启用。
- 缓存范围:一级缓存的范围是在同一个SqlSession内,因此只对同一个SqlSession中的查询操作有效。
- 缓存键:一级缓存的缓存键是由查询的SQL语句、查询参数、和Mapper接口的全限定名组成,以确保唯一性。
- 查询命中缓存:当执行查询时,MyBatis会首先检查一级缓存,如果缓存中已存在相同查询的结果,将直接从缓存中获取结果,而不再访问数据库。
- 写操作刷新缓存:一级缓存会自动刷新,当执行插入、更新、删除等写操作后,一级缓存中与写操作相关的查询结果会被自动清除,以确保缓存数据的一致性。
- 手动清除缓存:在某些情况下,开发者可以通过
SqlSession.clearCache()
方法手动清除一级缓存中的数据。
一级缓存使用场景:
- 适用于同一个SqlSession内频繁查询相同数据的情况,可以减少数据库查询次数。
- 对于一些频繁的查询操作,MyBatis可以通过一级缓存来提高查询性能。
一级缓存的注意事项:
- 一级缓存只在同一个SqlSession内有效,不适用于多个SqlSession之间的数据共享。
- 写操作会刷新一级缓存,确保缓存数据的一致性。如果在同一个SqlSession中执行写操作后,再次查询相同数据,会重新从数据库中获取数据。
- 在分布式系统中,不同的SqlSession无法共享一级缓存,需要考虑使用二级缓存来实现数据共享。
MyBatis二级缓存
MyBatis 一级缓存最大的共享范围就是一个SqlSession内部,那么如果多个 SqlSession 需要共享缓存,则需要开启二级缓存。
开启二级缓存后,会使用 CachingExecutor 装饰 Executor,进入一级缓存的查询流程前,先在 CachingExecutor 进行二级缓存的查询。
具体的工作流程如下所示:
当开启缓存后,数据的查询执行的流程就是 二级缓存 -> 一级缓存 -> 数据库。
二级缓存特点和行为:
- SqlSession之间共享:二级缓存是跨SqlSession的,允许不同SqlSession之间共享查询结果。
- 手动配置:二级缓存需要在MyBatis的配置文件中显式启用,并可以配置缓存的具体实现方式,如EhCache、Redis等。
- 全局范围:二级缓存的生命周期是与整个应用程序相关的,只有应用程序重启或手动清除缓存时,二级缓存中的数据才会失效。
- 缓存键:与一级缓存类似,二级缓存的缓存键是由查询的SQL语句、查询参数、和Mapper接口的全限定名组成,以确保唯一性。
- 查询命中缓存:当执行查询时,MyBatis会首先检查二级缓存,如果缓存中已存在相同查询的结果,将直接从缓存中获取结果,而不再访问数据库。
- 读写操作刷新缓存:对于写操作(插入、更新、删除等),会导致与写操作相关的查询结果从缓存中清除,以确保缓存数据的一致性。
- 手动清除缓存:开发者可以通过MyBatis提供的方法手动清除整个二级缓存或特定Namespace(Mapper接口)的缓存。
二级缓存使用场景:
- 适用于多个SqlSession之间需要共享相同数据的情况,可以减少数据库查询次数,特别在分布式应用程序中很有用。
二级缓存的注意事项:
- 二级缓存需要在MyBatis的配置文件中启用,并在Mapper接口或XML配置中指定哪些查询结果需要放入缓存。
- 在分布式系统中,不同的SqlSession可以共享二级缓存,从而实现数据共享,但需要谨慎考虑数据一致性和缓存的更新策略。
- 写操作(插入、更新、删除等)会刷新与写操作相关的查询结果,确保缓存数据的一致性。
- 二级缓存的性能受缓存实现的选择和配置的影响,开发者可以根据具体需求选择合适的二级缓存实现方式。