0%

hibernate检索策略

hibernate检索策略

hibernate一共提供了三种检索策略,一种为立即检索,除了立即检索之外还提供了两种检索策略,延迟检索迫切左外连接检索

  • 立即检索 会直接进行数据库访问,且立即执行,如果select语句过多,会频繁访问数据库
  • 延迟检索 避免了多余加载应用程序不需要访问的关联对象
  • 迫切左外连接检索 充分利用了SQL的外连接查询功能,减少了select语句的数目

类级别的检索策略

类级别的可选检索策略只有立即检索延迟检索

<class>元素中设置属性lazy 默认为true

  • 立即检索:立即加载检索方法指定的对象
  • 延迟检索:在调用load方法时不会执行select语句,而是返回一个代理对象,这个代理对象继承了原来对象的所有属性和方法(使用CGLIB生成的代理类),该代理类的实例仅初始化OID,所以占用的内存较少,只有在使用具体属性(除id之外的属性)的时候才会去执行select语句。代理对应的getter方法

只有在使用load方法的时候,lazy属性才会有用,在使用get()和list()方法时,只会使用立即检索

关联级别的检索策略

关联级别可选的检索策略有三种:立即检索延迟检索迫切左外连接检索

一对多和多对多检索策略

在set属性中配置一对多和多对多关联关系,<set>元素有lazy和fetch属性

  • lazy:主要决定<set>被初始化的时间,在加载主表时被初始化还是在访问该集合时被初始化 默认为true,有true(延迟检索)、extra(增强延迟检索)和false(立即检索)
    • true 在调用iterator()、size()、isEmpty()、contains方法时会进行初始化
    • extra 在调用iterator()方法时会进行初始化,而调用size()、isEmpty()、contains方法时,不会进行初始化,而是通过特定的select语句来查询必要的信息,而不是检索所有的对象
  • fetch:取值为select或subselect时,决定初始化<set>的查询语句形式;取值为join,决定<set>被初始化的时机,lazy属性将会被忽略,默认为select
    • select <set>元素中每条数据都会执行一条select语句
    • subselect 使用子查询,直接初始化set中所有的元素,使用 in (select id from zitable),此时batch-size属性被忽略
    • join 使用左外连接 (Query的list方法会忽略join,使用延迟检索)
  • batch-size:<set>中有一个batch-size属性,用来配置在延迟加载的情况下,每次加载几条数据,可以减少查询语句,提升性能(查询多条时使用in语句查询),仅适用于立即检索和延迟检索

对于<set>元素Hibernate是使用的代理类org.hibernate.collection.internal.PersistentSet

多对一和一对一检索策略

<many-to-one>元素和<one-to-one>中也包含lazy属性和fetch属性

  • lazy: proxy表示延时检索 no-proxy表示无代理延迟检索 false 表示立即检索 默认proxy
  • fetch:select表示每条数据使用一个select join表示使用左外连接 默认select
  • batch-size:可以在一的一端的<class>元素中设置batch-size,来配置一次初始化1的这一端的代理的个数,仅适用于立即检索和延迟检索

影响的方法有load方法、get方法以及Query和Criteria的API

在进行迫切左外连接时,由于过深的进行表连接会影响检索性能,所以hibernate设置了一个进行控制外连接深度的配置

hibernate.max_fetch_depth,该配置默认是2

欢迎关注我的其它发布渠道