1. 程式人生 > >hibernate的關聯,一對多(級聯新增,級聯查詢,普通刪除)

hibernate的關聯,一對多(級聯新增,級聯查詢,普通刪除)

一、什麼是關聯(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、普通刪除: