Mybatis 是一个 Java 持久层框架,它提供了灵活、高效的数据访问支持,其中数据查询功能更是 Mybatis 的一大特点。在我的博客中,我对 Mybatis 的两个重要特性进行了详细的解释,即延迟加载和缓存。
Mybatis 延迟加载
Mybatis 延迟加载是指,当查询数据时,不会立即将关联对象加载到内存中,而是采用按需获取的方式,当访问关联对象时才进行加载。这样可以减轻内存负担,提升查询效率,尤其是对于一些大型数据集查询和分页查询,效果更为显著。
延迟加载的实现
Mybatis 延迟加载的实现原理是使用代理对象来延迟加载关联对象。代理对象是在获取关联对象时创建的,它并不是真正的关联对象,而是继承了关联对象的接口,并覆盖了其中的逻辑。当代理对象的方法被调用时,才会去加载真正的关联对象。
延迟加载的配置
Mybatis 延迟加载的配置需要在 mapper.xml 文件中添加 lazyLoadingEnabled
和 aggressiveLazyLoading
两个属性的配置:
<settings>
<setting name="lazyLoadingEnabled" value="true" />
<setting name="aggressiveLazyLoading" value="false" />
</settings>
其中,lazyLoadingEnabled
用于开启延迟加载;aggressiveLazyLoading
用于指定是否在嵌套查询中开启延迟加载。如果开启了 aggressiveLazyLoading
,则 Mybatis 会尝试在嵌套查询中使用延迟加载,否则将会在嵌套查询中立即加载所有关联对象。
延迟加载的示例
下面是一个使用 Mybatis 延迟加载的示例:
// 获取用户信息和订单列表,但不立即加载订单详细信息
User user = userDao.findUserById(userId);
List<Order> orders = user.getOrders();
上述代码中,首先查询用户信息时只会加载用户的基本信息,而不会加载关联的订单信息。当需要获取订单列表时,才会去加载订单详细信息。这样可以避免一次性加载大量数据到内存中,提升查询效率。
Mybatis 缓存
Mybatis 缓存是指,在 Mybatis 中,对于相同的 SQL 语句和参数,获取的结果将被缓存,当再次查询时,可以直接从缓存中获取结果,从而避免了重复查询数据库的时间消耗。
缓存的实现
在 Mybatis 中,有一级缓存和二级缓存两种缓存方式。
一级缓存
Mybatis 的一级缓存是指在 SqlSession 中的缓存,它是一个 SqlSession 级别的缓存,只在同一 SqlSession 中有效,不同的 SqlSession 中的缓存不会互相影响。当查询相同的 SQL 语句和参数时,如果缓存中已经存在结果,就会直接返回缓存中的结果。在整个 SqlSession 生命周期中,同一个查询语句只会被执行一次,多次相同的查询会直接从缓存中获取结果,提高了查询效率。
二级缓存
Mybatis 的二级缓存是指在 SqlSessionFactory 中的缓存,它是一个全局性的缓存,对于同一 SqlSessionFactory 实例的所有 SqlSession 对象都是可见的。当一个 SqlSession 中执行了一个增、删、改操作时,会清空该 SqlSession 对应的所有数据缓存,以保证缓存数据的一致性。
缓存的配置
Mybatis 缓存的配置需要在 mapper.xml 文件中添加 <cache>
标签的配置:
<cache eviction="FIFO" flushInterval="60000" size="512" readOnly="true"/>
其中,eviction
属性用于指定缓存淘汰策略(FIFO/LRU),flushInterval
属性用于指定缓存刷新时间间隔,size
属性用于指定缓存大小,readOnly
属性用于指定是否开启只读缓存。
缓存的示例
下面是一个使用 Mybatis 缓存的示例:
// 获取用户信息,查询过程中将结果缓存
User user = userDao.findUserById(userId);
// 再次查询该用户信息,直接从缓存中获取结果
User userCached = userDao.findUserById(userId);
上述代码中,在第一次查询获取用户信息时,Mybatis 将结果缓存起来。当再次查询该用户信息时,直接从缓存中获取结果,避免了重复查询数据库的时间消耗。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Mybatis延迟加载和缓存深入讲解 - Python技术站