Hibernate 检索策略

Hibernate 的检索有两种:

  1:立即检索。立即加载检索方法指定的对象。

  2:延迟检索。延迟加载检索方法指定的对象。

好比老板让你去买包烟。然后1是拿着钱就去买了。2是先拿着钱。然后答应老板去买。等老板要抽烟的时候她才去买。

准备持久化类和相对应的映射文件。

package com.hibernate.strategy;

import java.util.HashSet;
import java.util.Set;

public class Customer {

    private Integer customerId;
    private String customerName;
    
    private Set<Order> orders = new HashSet<Order>();

    public Integer getCustomerId() {
        return customerId;
    }

    public void setCustomerId(Integer customerId) {
        this.customerId = customerId;
    }

    public String getCustomerName() {
        return customerName;
    }

    public void setCustomerName(String customerName) {
        this.customerName = customerName;
    }

    public Set<Order> getOrders() {
        return orders;
    }

    public void setOrders(Set<Order> orders) {
        this.orders = orders;
    }
   
}
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping package="com.hibernate.strategy">
    
    <class name="Customer" table="CUSTOMERS" lazy="true" batch-size="5">
    
        <id name="customerId" type="java.lang.Integer">
            <column name="CUSTOMER_ID" />
            <generator class="native" />
        </id>
    
        <property name="customerName" type="java.lang.String">
            <column name="CUSTOMER_NAME" />
        </property>
        
        <set name="orders" table="ORDERS" 
            inverse="true" order-by="ORDER_NAME DESC" >
            <key column="CUSTOMER_ID"></key>
            <one-to-many class="Order"/>
        </set>
        
    </class>
    
</hibernate-mapping>
package com.hibernate.strategy;

public class Order {
    
    private Integer orderId;
    private String orderName;
    
    private Customer customer;

    public Integer getOrderId() {
        return orderId;
    }

    public void setOrderId(Integer orderId) {
        this.orderId = orderId;
    }

    public String getOrderName() {
        return orderName;
    }

    public void setOrderName(String orderName) {
        this.orderName = orderName;
    }

    public Customer getCustomer() {
        return customer;
    }

    public void setCustomer(Customer customer) {
        this.customer = customer;
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((orderId == null) ? 0 : orderId.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Order other = (Order) obj;
        if (orderId == null) {
            if (other.orderId != null)
                return false;
        } else if (!orderId.equals(other.orderId))
            return false;
        return true;
    } 
}
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping package="com.hibernate.strategy">

    <class name="Order" table="ORDERS">

        <id name="orderId" type="java.lang.Integer">
            <column name="ORDER_ID" />
            <generator class="native" />
        </id>
        
        <property name="orderName" type="java.lang.String">
            <column name="ORDER_NAME" />
        </property>
        
        <many-to-one 
            name="customer" class="Customer" 
            column="CUSTOMER_ID"
            ></many-to-one>

    </class>
</hibernate-mapping>

开始操作:

  1:类级别的检索。通过设置<class>元素的lazy属性。

    1):get方法获得类对象。

@Test
    public void testLeiStrategy(){
        Customer customer=(Customer) session.get(Customer.class, 1);
        System.out.println(customer.getCustomerName());
        System.out.println(customer.getClass());
    }

解释:得到的是类本身。get是立即检索。

  2):load方法

1 @Test
2     public void testLeiStrategy(){
3         Customer customer=(Customer) session.load(Customer.class, 1);
4         System.out.println(customer.getCustomerName());
5         System.out.println(customer.getClass());
6     }

解释:返回的是一个代理对象。是延迟检索。

通过设置 

<class name="Customer" table="CUSTOMERS" lazy="false">

懒惰相反。就是立即加载。返回的也是一个customer类对象。

lazy="false"   只对load有效。对get无效。

2:一对多。多对多检索
<set name="orders" table="ORDERS" 
            inverse="true" order-by="ORDER_NAME DESC" >
            <key column="CUSTOMER_ID"></key>
            <one-to-many class="Order"/>
        </set>

因为无论是1对多,还是多对多。都是多的作为一个set集合,放到1 或多的中。其实就是对<set>设置。

  1):lazy:主要决定orders集合被初始化的时机。一共有三个设置。true 是默认的。false 立即加载。  extra就是增加延迟加载。就是比延迟加载还狠。

  2):fetch 决定初始化集合orders的查询语句的方式。

    1>:默认:select 正常的查询。

    2>:subselect   子查询的形式。因为是子查询。所以in()中需要order的ID。都要把set集合中的order都查询出来。batch-size会失效。

    3>:join  检索1一端的时候。采用迫切左外连接去检索集合order。lazy会失效。

@Test
    public void testGetFeth(){
        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.getOrders().size());
            }
        }
    }

fetch="subselect"  查询的结果

解释:把order都给初始化了。

用select:

Hibernate: 
    select
        customer0_.CUSTOMER_ID as CUSTOMER1_0_,
        customer0_.CUSTOMER_NAME as CUSTOMER2_0_ 
    from
        CUSTOMERS customer0_
4
Hibernate: 
    select
        orders0_.CUSTOMER_ID as CUSTOMER3_0_1_,
        orders0_.ORDER_ID as ORDER_ID1_1_1_,
        orders0_.ORDER_ID as ORDER_ID1_1_0_,
        orders0_.ORDER_NAME as ORDER_NA2_1_0_,
        orders0_.CUSTOMER_ID as CUSTOMER3_1_0_ 
    from
        ORDERS orders0_ 
    where
        orders0_.CUSTOMER_ID=? 
    order by
        orders0_.ORDER_NAME desc
2
Hibernate: 
    select
        orders0_.CUSTOMER_ID as CUSTOMER3_0_1_,
        orders0_.ORDER_ID as ORDER_ID1_1_1_,
        orders0_.ORDER_ID as ORDER_ID1_1_0_,
        orders0_.ORDER_NAME as ORDER_NA2_1_0_,
        orders0_.CUSTOMER_ID as CUSTOMER3_1_0_ 
    from
        ORDERS orders0_ 
    where
        orders0_.CUSTOMER_ID=? 
    order by
        orders0_.ORDER_NAME desc
2
Hibernate: 
    select
        orders0_.CUSTOMER_ID as CUSTOMER3_0_1_,
        orders0_.ORDER_ID as ORDER_ID1_1_1_,
        orders0_.ORDER_ID as ORDER_ID1_1_0_,
        orders0_.ORDER_NAME as ORDER_NA2_1_0_,
        orders0_.CUSTOMER_ID as CUSTOMER3_1_0_ 
    from
        ORDERS orders0_ 
    where
        orders0_.CUSTOMER_ID=? 
    order by
        orders0_.ORDER_NAME desc
3
Hibernate: 
    select
        orders0_.CUSTOMER_ID as CUSTOMER3_0_1_,
        orders0_.ORDER_ID as ORDER_ID1_1_1_,
        orders0_.ORDER_ID as ORDER_ID1_1_0_,
        orders0_.ORDER_NAME as ORDER_NA2_1_0_,
        orders0_.CUSTOMER_ID as CUSTOMER3_1_0_ 
    from
        ORDERS orders0_ 
    where
        orders0_.CUSTOMER_ID=? 
    order by
        orders0_.ORDER_NAME desc
1

需要1次查询一次。

  3>:join

@Test
    public void testSetFetch2(){
        Customer customer = (Customer) session.get(Customer.class, 1);
        System.out.println(customer.getOrders().size()); 
    }
Hibernate: 
    select
        customer0_.CUSTOMER_ID as CUSTOMER1_0_1_,
        customer0_.CUSTOMER_NAME as CUSTOMER2_0_1_,
        orders1_.CUSTOMER_ID as CUSTOMER3_0_3_,
        orders1_.ORDER_ID as ORDER_ID1_1_3_,
        orders1_.ORDER_ID as ORDER_ID1_1_0_,
        orders1_.ORDER_NAME as ORDER_NA2_1_0_,
        orders1_.CUSTOMER_ID as CUSTOMER3_1_0_ 
    from
        CUSTOMERS customer0_ 
    left outer join
        ORDERS orders1_ 
            on customer0_.CUSTOMER_ID=orders1_.CUSTOMER_ID 
    where
        customer0_.CUSTOMER_ID=? 
    order by
        orders1_.ORDER_NAME desc
2

3:多对1  1对1

都是把1的一方放到多的。作为多的一个属性。

<many-to-one 
            name="customer" class="Customer" 
            column="CUSTOMER_ID"></many-to-one>

 false  :默认的。

proxy :延迟加载。

no-proxy:无代理延迟加载。

fetch只有2个

原文地址:https://www.cnblogs.com/bulrush/p/7811867.html