hibernate的检索策略

Hibernate的检索策略分为三种

1类级别的检索策略,操作级别就是在单独一个表里面,不牵连其他表

类级别的检索策略(仅仅适合load()方法)(就是设置<class>节点是的lazy属性true或FALSE 默认是true)
无论 <class> 元素的 lazy 属性是 true 还是 false, Session 的 get() 方法及 Query 的 list() 方法在类级别总是使用立即检索策略
若 <class> 元素的 lazy 属性为 true 或取默认值, Session 的 load() 方法不会执行查询数据表的 SELECT 语句, 仅返回代理类对象的实例,(称之为延迟加载) 
该代理类实例有如下特征: 1由 Hibernate 在运行时采用 CGLIB 工具动态生成 2Hibernate 创建代理类实例时, 仅初始化其 OID 属性(因为在load的时候传递了OID) 3在应用程序第一次访问代理类实例的非 OID 属性时, Hibernate 会初始化代理类实例

2关联关系的检索策略(其实就是对set标签的lazy、batch-size、fetch属性进行需要性设置)

在一对多和多对多的映射文件中,用 <set> 元素来配置关联关系时.(customer(1),order(n))
<set> 元素有 lazy 和 fetch 属性 lazy: 加载属性,主要决定order集合被初始化的时机. 即到底是在加载 Customer 对象时就初始化order对象, 还是在程序访问orders 集合时再初始化的对象
    默认值是true 
     -------------------------set 的 lazy 属性的取值---------------------------------------------------
        true-默认:使用懒加载方式:就是在加载 Customer 对象时不初始化order对象,在程序访问order集合对象才初始order对象
     false:不是使用懒加载的模式,
在加载 Customer 对象时就初始化order对象(比较浪费内存,一般不建议)
     extra:使用增强的延迟加载模式,在加载 Customer 对象时不初始化order对象,并且在访问order集合的size()和isEmpty()方法还没初始化order对象,只是         方式select语句去查询统计个数,不会初始化order对象,等到访问到order集合的iterator()方法才初始化order对象
         initialize()方法强制初始化集合对象(一般推荐这样使用)(大部分时候默认值就可以了)

<set> 元素的 batch-size 属性:设定一次初始化 set 集合的数量. 用来为延迟检索策略或立即检索策略设定批量检索的数量. 批量检索能减少 SELECT 语句的数目, 提高延迟检索或立即检索的运行性能. 
注意
初始化的集合不是被关联的对象:batch-size初始化的值代表是当前运行的set<>集合的对象,并不一定是被关联的对象
example:
@Test
    public void testSetBatchSize(){
        List<Customer> customers = session.createQuery("FROM Customer").list();
        
        System.out.println(customers.size()); 
        
        for(Customer customer: customers){
            if(customer.getOrders() != null)
                System.out.println(customer.getCustomerName());
                System.out.println(customer.getOrders().iterator().next().getOrderName());
                System.out.println(customer.getOrders().getClass());
        }

运行上面的代码可以知道,初始化的只是list<>集合,但是并没有初始化被关联的对象order,所以batch-size初始化的值是当前方法set<>集合的对象,并不是被关联的对象(order)

set 集合的 fetch 属性: 有两种作用
I确定初始化 orders 集合(被关联对象)的方式.
1. 默认值为 select. 通过select方式来初始化set对象---就是发送select * from order where customer.id in(1,2,3,4,5...)
2. 可以取值为 subselect.通过子查询的方式来初始化所有的 set 集合和所有被关联的对象. 子查询作为 where 子句的 in 的条件出现, 子查询查询所有 1 的一端的 ID.
发送select * from orders where customer.id in(select id from customer)
  batch-size 失效(因为subselect在需要检索的时候就一次性初始化关联的对象)
II确定是否使用迫切左外连接(决定关联对象初始化时机)
3. 若取值为 join.则决定 orders 集合和被关联对象被初始化的时机,也就是说lazy失效(一般在多对一和一对一是使用,因为在此时查多端的对象时一般都要用到一端的对象,)
3.1 在加载 1 的一端的对象时, 同时也使用迫切左外连接(使用左外链接进行查询, 且把集合属性进行初始化了)的方式检索 n 的一端的集合属性
3.2 忽略 lazy 属性.
3.3 HQL(就是Hibernate的查询数据库的语句(跟sql不同))查询忽略 fetch=join 的取值

 

posted @ 2014-10-09 20:22  Jeremy_software  阅读(191)  评论(0编辑  收藏  举报