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;}@Overridepublic int hashCode() {final int prime = 31;int result = 1;result = prime * result + ((orderId == null) ? 0 : orderId.hashCode());return result;}@Overridepublic 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方法获得类对象。
@Testpublic 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会失效。
@Testpublic 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: selectcustomer0_.CUSTOMER_ID as CUSTOMER1_0_,customer0_.CUSTOMER_NAME as CUSTOMER2_0_ fromCUSTOMERS customer0_ 4 Hibernate: selectorders0_.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_ fromORDERS orders0_ whereorders0_.CUSTOMER_ID=? order byorders0_.ORDER_NAME desc 2 Hibernate: selectorders0_.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_ fromORDERS orders0_ whereorders0_.CUSTOMER_ID=? order byorders0_.ORDER_NAME desc 2 Hibernate: selectorders0_.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_ fromORDERS orders0_ whereorders0_.CUSTOMER_ID=? order byorders0_.ORDER_NAME desc 3 Hibernate: selectorders0_.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_ fromORDERS orders0_ whereorders0_.CUSTOMER_ID=? order byorders0_.ORDER_NAME desc 1
需要1次查询一次。
3>:join
@Testpublic void testSetFetch2(){Customer customer = (Customer) session.get(Customer.class, 1);System.out.println(customer.getOrders().size()); }
Hibernate: selectcustomer0_.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_ fromCUSTOMERS customer0_ left outer joinORDERS orders1_ on customer0_.CUSTOMER_ID=orders1_.CUSTOMER_ID wherecustomer0_.CUSTOMER_ID=? order byorders1_.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个