缓存级别
MyBatis 提供了两个级别的缓存:一级缓存和二级缓存。它们的作用和使用场景如下所示:
一级缓存(SqlSession 级别缓存):
作用范围:一级缓存是在单个 SqlSession 内部有效,因此对于同一个 SqlSession 中执行的相同查询,查询结果会被缓存在一级缓存中。
提高性能:当多次执行相同查询时,从一级缓存中获取结果,避免再次向数据库发起查询请求,可以提高查询性能。
减少数据库压力:由于查询结果已经缓存在一级缓存中,避免了重复的数据库查询,从而减少了数据库的压力。
自动刷新:一级缓存会在执行插入、更新、删除等修改操作时自动刷新,确保数据的一致性。
一般无需过多关注和配置,是默认开启的。
二级缓存(Mapper 级别缓存):
作用范围:二级缓存是跨 SqlSession 的缓存,可以被多个 SqlSession 共享(即多个不同的 SqlSession 可以共享相同的缓存数据)。
接口级别的缓存:二级缓存是基于 Mapper 接口的,即同一个 Mapper 接口的不同 SqlSession 可以共享相同的缓存数据。
架构级别的缓存:当多个应用实例之间共享同一个数据库,使用二级缓存可以提高系统整体的性能。
手动配置:需要手动在 MyBatis 的配置文件中开启二级缓存,并在 Mapper 接口方法上加入相应的注解或 XML 配置。
可选的缓存实现:MyBatis提供了多种二级缓存实现,如基于内存的 PerpetualCache 和基于 Redis 的 RedisCache 等,可以根据实际需求选择合适的缓存实现方式。
综上所述,MyBatis 缓存的不同级别都能提供缓存结果以减少访问数据库的次数,提高查询性能和系统整体性能。一级缓存适用于同一个 SqlSession 内的重复查询,而二级缓存适用于多个 SqlSession 共享同一数据源的情况。
缓存的缓存级别
MyBatis 缓存的缓存级别主要有三个:Statement 级别缓存、SqlSession 级别缓存以及 Mapper 接口级别缓存。下面分别对这三个级别的缓存进行详细介绍:
-
Statement 级别缓存(Local Cache):
- 作用范围:Statement 级别缓存是在 SQL 执行环境内的缓存,用于缓存同一个 SQL 语句的执行结果。
- 生命周期:Statement 级别缓存的生命周期是短暂的,仅限于同一个 SQL 语句执行过程中的多次查询,即在同一个 SQL 语句执行期间,后续执行相同的 SQL 语句可以直接从缓存中获取结果。
- 默认开启:Statement 级别缓存在 MyBatis 中默认是开启的,会根据配置进行相关操作。
- 适用场景:适用于多次执行相同 SQL 语句的查询,提高查询性能,但不适用于缓存结果跨 SQL 语句的查询。
-
SqlSession 级别缓存(Per-Session Cache):
- 作用范围:SqlSession 级别缓存是在同一个 SqlSession 内部有效,对于同一个 SqlSession 中执行的相同查询,查询结果会被缓存在一级缓存中。
- 生命周期:SqlSession 级别缓存的生命周期与 SqlSession 的生命周期一致,在 SqlSession 关闭之后缓存将失效。
- 自动刷新:在执行插入、更新、删除操作时,SqlSession 级别缓存会自动刷新,保证数据的一致性。
- 默认开启:一级缓存在 MyBatis 中默认是开启的,通常无需手动配置。
- 适用场景:适用于同一个 SqlSession 内多次执行相同查询,避免重复的数据库查询,提高查询性能,但不能在多个 SqlSession 之间共享缓存结果的情况。
-
Mapper 接口级别缓存(Mapper Cache):
- 作用范围:Mapper 接口级别缓存是在 Mapper 接口的方法级别上进行缓存,可由多个 SqlSession 对象共享。
- 生命周期:Mapper 接口级别缓存的生命周期与应用程序一致,在应用程序关闭之前一直有效。
- 手动配置:需要在 MyBatis 的配置文件中开启二级缓存,并在 Mapper 接口方法上添加相应的注解或 XML 配置。
- 可选的缓存实现:MyBatis 提供了多种二级缓存实现,如基于内存的
PerpetualCache
和基于 Redis 的RedisCache
等。 - 适用场景:适用于多个 SqlSession 对象之间共享相同查询结果的场景,可提高系统整体性能。
综上所述,MyBatis 提供了三个级别的缓存:Statement 级别缓存在 SQL 语句执行期间生效,SqlSession 级别缓存在同一个 SqlSession 内部有效,Mapper 接口级别缓存在多个 SqlSession 之间共享。
MyBatis 默认使用的是 SqlSession 级别的缓存(Per-Session Cache)。该缓存级别是在同一个 SqlSession 中进行的缓存,对于同一个 SqlSession 中执行的相同查询,查询结果会被缓存在一级缓存中。SqlSession 级别的缓存在 MyBatis 中是默认开启的,通常无需手动配置。
sqlsession 是针对每个http请求吗
SQLSession 不是针对每个 HTTP 请求的,而是针对每个数据库连接的。
在使用 SQLSession 时,我们需要先创建一个数据库连接,然后通过这个连接创建一个 SQLSession 对象。在一个数据库连接中,可以创建多个 SQLSession 对象,这些 SQLSession 对象可以在不同的线程中使用,执行数据库的查询、插入、更新和删除等操作。
在一个 HTTP 请求中,可以重用之前的 SQLSession 对象,从而实现数据库操作的复用,提高性能。但是需要注意,在多线程的环境中,每个线程需要拥有自己的 SQLSession 对象,不要共享同一个 SQLSession 对象,以免发生线程安全的问题。
SQLSession的创建在单实例中会重建吗
在单实例中,SQLSession 的创建一般是在应用程序启动时进行,然后在整个应用程序的生命周期中重用同一个 SQLSession 对象。这样可以减少数据库连接的创建和销毁的开销,提高数据库操作的性能。
所以,在单实例中,不会频繁地创建和销毁 SQLSession 对象。一般情况下,在应用程序启动时创建 SQLSession 对象,并在应用程序关闭时手动关闭 SQLSession 对象。
需要注意的是,虽然在单实例中重用同一个 SQLSession 对象,但每个线程仍然需要拥有自己的 SQLSession 对象,以免发生线程安全的问题。可以使用线程池或者 ThreadLocal 来管理 SQLSession 对象,在每个线程中获取自己的 SQLSession 对象,从而保证线程安全。