hibernate的關聯,一對多(級聯新增,級聯查詢,普通刪除)
阿新 • • 發佈:2018-12-17
一、什麼是關聯(association)
1、關聯指的是類之間的引用關係。如果類A與類B關聯,那麼被引用的類B將被定義為類A的屬性。 2、關聯的分類:關聯可以分為一對一、一對多/多對一、多對多關聯
關聯是有方向的
關聯的關鍵點都在外來鍵上
二、如何建立一對多雙向關聯
以訂單和訂單項做案例
一個訂單對多個訂單項,多個訂單項對一個訂單
在訂單實體類中需要新增兩個屬性 : Set<OrderItem> orderItems
initOrderItems = 0;//0代表懶載入 1代表立即載入
在訂單項的實體類中需要新增一個屬性:Order order
定義一對多的關係時需要採用介面方式
1、在Order.hbm.xml中需要新增(建立訂單對訂單項的一對多的關係)
<!--
cascade:用來配置維護實體類之間的關係所用
inverse:關係交由反方控制(由OrderItem控制)
-->
<set name="orderItems" cascade="save-update" inverse="true">
<!-- 填外來鍵 -->
<key column="oid"></key>
<one-to-many class="com.zking.four.entity.OrderItem"/>
</set>
2、在OrderItem.hbm.xml中需要新增(建立訂單項對訂單多對一的關係)
<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>
三、級聯新增、級聯查詢,普通刪除
方法:
package com.zking.four.dao; import java.util.List; import org.hibernate.Hibernate; import org.hibernate.Session; import org.hibernate.Transaction; import com.zking.four.entity.Order; import com.zking.four.entity.OrderItem; import com.zking.two.util.SessionFactoryUtil; public class OrderDao { //訂單項新增 public Integer addOrderItem(OrderItem orderItem) { Session session = SessionFactoryUtil.getSession(); Transaction transaction = session.beginTransaction(); Integer otid = (Integer) session.save(orderItem); transaction.commit(); session.close(); return otid; } //訂單新增 public Integer addOrder(Order order) { Session session = SessionFactoryUtil.getSession(); Transaction transaction = session.beginTransaction(); Integer otid = (Integer) session.save(order); transaction.commit(); session.close(); return otid; } //查單個 public Order getOrder(Order order) { Session session = SessionFactoryUtil.getSession(); Transaction transaction = session.beginTransaction(); Order o = session.get(Order.class, order.getOrderId()); if(o != null && new Integer(1).equals(order.getInitOrderItems())) { Hibernate.initialize(o.getOrderItems()); } transaction.commit(); session.close(); return o; } //查所有 public List<Order> getOrderList(){ Session session = SessionFactoryUtil.getSession(); Transaction transaction = session.beginTransaction(); List list = session.createQuery("from Order").list(); transaction.commit(); session.close(); return list; } //刪除(hibernate需要先刪從表(訂單項)再刪主表(訂單)) public void delOrder(Order order) { Session session = SessionFactoryUtil.getSession(); Transaction transaction = session.beginTransaction(); Order o = session.get(Order.class, order.getOrderId()); for (OrderItem ot : o.getOrderItems()) { session.delete(ot); } session.delete(o); transaction.commit(); session.close(); } }
JUnit測試
package com.zking.four.dao;
import java.util.Iterator;
import java.util.List;
import org.junit.Test;
import com.zking.four.entity.Order;
import com.zking.four.entity.OrderItem;
public class OrderDaoTest {
private OrderDao orderDao = new OrderDao();
/**
* Repeated column in mapping for entity:
* com.zking.four.entity.OrderItem column: oid
* (should be mapped with insert="false" update="false")
* 同一個欄位被映射了兩次
*/
@Test
public void testAddOrderItem() {//訂單項新增
OrderItem orderItem = new OrderItem();
// orderItem.setOid(7);//普通新增
orderItem.setProductId(89);
orderItem.setQuantity(78);
Order order = new Order();
order.setOrderId(5);
orderItem.setOrder(order);
this.orderDao.addOrderItem(orderItem);
}
//提交一個具有6個訂單項的訂單
// addOrder 1
// addOrderItem 6
@Test
public void testAddOrder() {//訂單新增
Order order = new Order();
order.setOrderNo("P8");
OrderItem orderItem;
for (int i = 1; i < 7; i++) {
orderItem = new OrderItem();
orderItem.setProductId(i);
orderItem.setQuantity(i);
order.getOrderItems().add(orderItem);
orderItem.setOrder(order);
}
this.orderDao.addOrder(order);
}
@Test
public void testGetOrder() {//查單個
Order order = new Order();
order.setOrderId(8);
order.setInitOrderItems(1);
Order o = this.orderDao.getOrder(order);
System.out.println(o.getOrderNo());
System.out.println(o.getOrderItems().size());
for (OrderItem ot : o.getOrderItems()) {
System.out.println(ot.getProductId());
}
}
@Test
public void testGetOrderList() {//查所有
List<Order> list = this.orderDao.getOrderList();
for (Order o : list) {
System.out.println(o.getOrderNo());
System.out.println(o.getOrderItems().size());
for (OrderItem ot : o.getOrderItems()) {
System.out.println(ot.getProductId());
}
}
}
@Test
public void testDelOrder() {//刪除
Order order = new Order();
order.setOrderId(8);
this.orderDao.delOrder(order);
}
}
1、級聯新增: 外來鍵處理的三種方式 ①、刪除從表對應的實體類中的外來鍵屬性 ②、在配置的xml中外來鍵屬性上新增 insert=false,update=false的設定。 ③、在配置的xml中的manyToOne標籤中新增insert=false,update=false的設定。
<property name="oid" type="java.lang.Integer" column="oid" insert="false" update="false"></property>
級聯新增 casecade=save-update 介紹
<set lazy="false" name="orderItems" cascade="save-update" inverse="true">
2、級聯查詢: 配置檔案介紹以及後臺sql的形成過程 級聯查詢時的問題 Lazy=true介紹 查單個時存在問題 Lazy=false介紹 查所有時存在問題
<set lazy="false" name="orderItems" cascade="save-update" inverse="true">
解決方案:通過欄位控制,強制載入。Hibernate.initialize()
3、普通刪除: