zoukankan      html  css  js  c++  java
  • 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 的取值
  • 相关阅读:
    js实现多物体运动框架并兼容各浏览器
    JAVA-day08 下午-总结、測试
    更改Android应用程序的图标
    codeforces #296 div2 (527C) STL中set的运用
    曼昆微观经济学之征税的市场本质—冰激凌篇
    POJ 1789:Truck History(prim&amp;&amp;最小生成树)
    Android:Activity+Fragment及它们之间的数据交换(一)
    滴滴拉屎之后是什么?
    tmux安装
    IOS开发——Core Graphics &amp; Core Animation
  • 原文地址:https://www.cnblogs.com/jeremy-blog/p/4014319.html
Copyright © 2011-2022 走看看