mybatis延迟加载模式

什么是延迟加载

当我们在使用MyBatis进行数据库查询时,通常会使用一种称为“立即加载”的方式。这意味着当查询主对象时,MyBatis会立即加载该对象及其关联对象的所有数据。但是,有时关联对象的数据可能会很大,而且并不一定每次都需要完整加载所有的关联对象数据。这就是延迟加载的作用。

延迟加载是一种性能优化技术,它允许在需要的时候才去加载关联对象的数据,而不是在查询主对象时就一次性加载所有关联对象。这样可以避免不必要的数据库查询,提高查询性能和减轻数据库负载。

延迟加载的两种方式

基于proxy的延迟加载

MyBatis使用代理对象来延迟加载关联对象的数据。当访问关联属性时,MyBatis会生成一个代理对象并返回,而不是立即加载关联对象的数据。只有在实际使用关联对象的属性时,才会触发MyBatis执行额外的查询从数据库中加载关联对象的数据。

基于select的延迟加载

MyBatis使用额外的select语句来延迟加载关联对象的数据。在查询主对象时,关联对象的数据并不会被加载,只有在访问关联属性时才会执行额外的查询语句加载关联对象的数据。  

mybatis延迟加载的优缺点

优点:

  1. 减轻数据库压力:延迟加载可以避免一次性加载所有的关联对象数据,只在需要时加载,减少了不必要的数据库查询。这减轻了数据库的负载,提高了系统的性能和响应速度。

  2. 提高查询性能:延迟加载可以减少数据库查询的数量,特别是在关联对象数据较大、复杂的情况下。只有在实际需要使用关联对象数据时才加载,避免了不必要的关联对象数据的提取和传输,从而提高了查询性能和效率。

  3. 减少内存消耗:延迟加载可以减少内存消耗,特别是在查询的数据结构比较复杂时。当关联对象数据并不是经常使用时,可以避免一次性加载所有数据,减少内存的占用,提高系统的运行效率。

缺点:

  1. N+1查询问题:延迟加载容易引发N+1查询问题。当关联对象数据被访问时,如果每次都执行额外的查询语句加载数据,可能会导致大量的额外查询操作,增加了数据库的访问压力。

  2. 额外的查询语句:延迟加载需要额外的查询语句来加载关联对象的数据,这可能会增加数据库的访问次数和网络开销。在一些复杂的查询场景下,可能需要执行多次查询才能获取到完整的关联对象数据。

  3. 会话限制:延迟加载要求数据库会话保持开启状态,以便在访问关联对象属性时能够实时加载数据。如果会话在访问关联对象之前被关闭,可能导致无法加载关联对象数据的异常。

如何开启延迟加载

mybatis-plus

# MyBatis-Plus 配置
mybatis-plus:
  global-config:
    db-config:
      # 开启延迟加载
      # 注意:这里延迟加载必须设置为 true ,默认为 false
      logic-not-delete-value: 0
      logic-delete-value: 1
      # 开启实体属性下划线到驼峰命名的自动映射
      column-underline: true
  configuration:
    # 开启MyBatis-Plus延迟加载
    lazy-loading-enabled: true
    # 开启MyBatis-Plus关联对象延迟加载
    lazy-loading-enabled-on-relation: true

 mybatis

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/mydatabase
    username: username
    password: password

mybatis:
  mapper-locations: classpath:mapper/*.xml
  configuration:
    lazy-loading-enabled: true

适合开启延迟加载的场景

  1. 关联对象的数据量较大:当关联对象的数据量较大时,开启延迟加载可以避免一次性加载所有的关联对象数据,减少不必要的数据库查询和网络开销。特别是在一对多或多对多的关联关系中,延迟加载可以显著减少数据库查询次数和数据传输量,提高系统的性能。

  2. 访问关联对象数据比较少:当我们在查询主对象时,并不总是需要获取关联对象的所有数据。如果只有在实际需要使用关联对象数据时才加载,可以避免不必要的数据提取和传输,减少内存消耗,并提高系统的运行效率。

  3. 页面分页查询:在分页查询时,开启延迟加载可以避免一次性加载所有的关联对象数据。只有在需要显示关联对象数据的当前页时才加载,可以提高查询性能和用户体验。这种场景下,延迟加载可以很好地配合分页查询,避免查询大量的数据造成性能 bottleneck。

  4. 嵌套查询较深的情况:当查询的对象存在多层嵌套关系时,开启延迟加载可以避免层层递归查询造成的性能问题。只有在需要使用关联对象数据时才加载,可以减少多次递归查询的开销。

你可能感兴趣的:(mybatis,oracle,数据库)