Hibernate:級聯查詢
阿新 • • 發佈:2018-12-17
案例:訂單類和訂單項類
級聯查詢時的問題 Lazy=true介紹 查單個時存在問題 Lazy=false介紹 查所有時存在問題 在set裡把lazy=“false”也可以所報的錯(com.zking.four.entity.Order.orderItems, could not initialize proxy - no Session) <set lazy="false" name="orderItems" cascade="save-update" inverse="true"> 解決方案:通過欄位控制,強制載入。Hibernate.initialize()
不在order類加initOrderItems欄位時,會報錯
1.order類
package com.zking.four.entity; import java.util.HashSet; import java.util.Set; public class Order { private Integer orderId; private String orderNo; //定義一對多的關係時一定需要採用介面方式,不許使用實現類 //implements java.util.Set 代理實現的是set介面 private Set<OrderItem> orderItems=new HashSet<OrderItem>(); private Integer initOrderItem=0;//0代表懶載入 1代表立即載入 public Integer getInitOrderItem() { return initOrderItem; } public void setInitOrderItem(Integer initOrderItem) { this.initOrderItem = initOrderItem; } public Set<OrderItem> getOrderItems() { return orderItems; } public void setOrderItems(Set<OrderItem> orderItems) { this.orderItems = orderItems; } public Integer getOrderId() { return orderId; } public void setOrderId(Integer orderId) { this.orderId = orderId; } public String getOrderNo() { return orderNo; } public void setOrderNo(String orderNo) { this.orderNo = orderNo; } }
2.orderItem類
package com.zking.four.entity; public class OrderItem { private Integer orderItemId; private Integer productId; private Integer quaneity; private Integer oid; private Order order; public Order getOrder() { return order; } public void setOrder(Order order) { this.order = order; } public Integer getOrderItemId() { return orderItemId; } public void setOrderItemId(Integer orderItemId) { this.orderItemId = orderItemId; } public Integer getProductId() { return productId; } public void setProductId(Integer productId) { this.productId = productId; } public Integer getQuaneity() { return quaneity; } public void setQuaneity(Integer quaneity) { this.quaneity = quaneity; } public Integer getOid() { return oid; } public void setOid(Integer oid) { this.oid = oid; } }
3.order.hbm.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class table="t_hibernate_order" name="com.zking.four.entity.Order">
<id name="orderId" type="java.lang.Integer" column="order_id ">
<generator class="increment"></generator>
</id>
<property name="orderNo" type="java.lang.String" column="order_no "></property>
<!--
name:實體類的類屬性
cascade:用來配置維護實體類之間的關係所用
inverse:(inverse="true")關係交由反方控制 即訂單項 因為現在配置的是訂單,所以反方是訂單項
(inverse="true") 關係由自己控制 訂單
lazy="false":立即載入
-->
<set lazy="false" name="orderItems" cascade="save-update" inverse="true">
<!-- 訂單項外來鍵 -->
<key column="oid"></key>
<!-- 一個訂單對應多個訂單項 -->
<one-to-many class="com.zking.four.entity.OrderItem"></one-to-many>
</set>
</class>
</hibernate-mapping>
4.orderItem.hbm.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class table="t_hibernate_order_item" name="com.zking.four.entity.OrderItem">
<id name="orderItemId" type="java.lang.Integer" column="order_item_id ">
<generator class="increment"></generator>
</id>
<property name="productId" type="java.lang.Integer" column="product_id "></property>
<property name="quaneity" type="java.lang.Integer" column="quantity "></property>
<property name="oid" type="java.lang.Integer" column="oid" insert="false" update="false"></property>
<many-to-one name="order" class="com.zking.four.entity.Order" column="oid"></many-to-one>
</class>
</hibernate-mapping>
5.dao方法
public class OrderDao(){
//單個查
public Order getOrder(Order order) {
Session session = SessionFactoryUtils.getSession();
Transaction transaction = session.beginTransaction();
Order o = session.get(Order.class,order.getOrderId());
if(o!=null&&new Integer(1).equals(order.getInitOrderItem())) {
Hibernate.initialize(o.getOrderItems()); //預設強制載入
}
transaction.commit();
session.close();
return o;
}
//查所有
public List<Order> listOrder() {
Session session = SessionFactoryUtils.getSession();
Transaction transaction = session.beginTransaction();
System.out.println(123);
List list = session.createQuery("from Order").list();
System.out.println(345);
transaction.commit();
session.close();
return list;
}
}
6.測試類:
public class OrderDaoTest {
private OrderDao orderDao=new OrderDao();
private OrderItem orderItem=new OrderItem();
private Order order=new Order();
/**
* com.zking.four.entity.Order.orderItems,
* could not initialize proxy - no Session
* 懶載入
*
* hibernate3 以後預設是懶載入 效能調優 關聯的東西出不來
*
*
*/
@Test
public void testGetOrder() {
order.setOrderId(2);
order.setInitOrderItem(1);
Order o = this.orderDao.getOrder(order);
System.out.println(o.getOrderNo());
System.out.println(o.getOrderItems().size());
for (OrderItem oi : o.getOrderItems()) {
System.out.println(oi.getProductId());
}
}
/**
*
* 在單查訂單的時候,會預設查詢訂單項,sql語句就會執行很多次 耗效能
*
* Lazy=false 可以解決報錯問題 使懶載入變為立即載入 但是效能差
*/
@Test
public void testListOrder() {
List<Order> listOrder = this.orderDao.listOrder();
for (Order o : listOrder) {
System.out.println(o.getOrderNo());
System.out.println(o.getOrderItems().size());
for (OrderItem oi : o.getOrderItems()) {
System.out.println(oi.getProductId());
}
}
}
}
單個查結果:
查所有結果:
查詢所有,是有n條資料就執行了n+1次sql查詢語句(一條訂單查詢,n條訂單項查詢)
查詢的解決:只要把set裡的lazy設定為false使懶載入變成立即載入就可以實現查所有的方法了,但是因為sql語句執行的多了,功能效能就差了
<set lazy="false" name="orderItems" cascade="save-update" inverse="true">