hibernate一对多的关系

什么是关联(association)

1.1 关联指的是类之间的引用关系。如果类A与类B关联,那么被引用的类B将被定义为类A的属性。例如:

 class B{
		private String name;
	  }
	  
	  public class A{
        private B b = new B;
        public A(){}
      }

1.2 关联的分类:关联可以分为一对一、一对多/多对一、多对多关联
关联是有方向的

案例展示

  1. 先写好实体类
    Order
package com.xfz.three.entity;

import java.util.ArrayList;
import java.util.List;

public class Order {
	private Integer orderId;
	private String orderNo;
	private List orderItems=new ArrayList<>();
	private Integer inintChildren=0;//0表示默认加载,1代表强制加载
	
	public Integer getInintChildren() {
		return inintChildren;
	}
	public void setInintChildren(Integer inintChildren) {
		this.inintChildren = inintChildren;
	}
	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;
	}
	public List getOrderItems() {
		return orderItems;
	}
	public void setOrderItems(List orderItems) {
		this.orderItems = orderItems;
	}
	@Override
	public String toString() {
		return "Order [orderId=" + orderId + ", orderNo=" + orderNo + ", orderItems=" + orderItems + "]";
	}
	
	
}

OrderItem

package com.xfz.three.entity;

public class OrderItem {
	private Integer orderItemId;
	private Integer productId;
	private Integer quantity;
	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 getQuantity() {
		return quantity;
	}
	public void setQuantity(Integer quantity) {
		this.quantity = quantity;
	}
	public Integer getOid() {
		return oid;
	}
	public void setOid(Integer oid) {
		this.oid = oid;
	}
	@Override
	public String toString() {
		return "OrderItem [orderItemId=" + orderItemId + ", productId=" + productId + ", quantity=" + quantity
				+ ", oid=" + oid + "]";
	}

}

  1. 再写好实体类的映射文件
    Order



	
		
			
		
		
		
		
	    
	    	
	    	
	    
	


OrderItem




	
		
			
		
		
		
		
		
		
		
		
		
	

  1. 导入所写好的dao方法
package com.xfz.three.dao;

import java.util.List;

import org.hibernate.Session;
import org.hibernate.Transaction;

import com.xfz.three.entity.Order;
import com.xfz.three.entity.OrderItem;
import com.xfz.two.util.SessionFactoryUtils;

public class DemoDao {
	/**
	 * 为了测试关系型映射文件配置准确
	 * 	讲解insert=false,update=false的用途
	 * @param order
	 * @return
	 */
	public Integer addOrder(Order order) {
		Session session = SessionFactoryUtils.openSession();
		Transaction transaction = session.beginTransaction();
		Integer oid = (Integer)session.save(order);
		transaction.commit();
		session.close();
		return oid;
	}
	
	public Integer addOrderItem(OrderItem orderItem) {
		Session session = SessionFactoryUtils.openSession();
		Transaction transaction = session.beginTransaction();
		Integer otid = (Integer)session.save(orderItem);
		transaction.commit();
		session.close();
		return otid;
	}
	
	
	
	/**
	 * 为了讲解懒加载的问题(hibernate3.0后所有查询方式默认采用的是懒加载方式)
	 * 	1、查单个时存在问题,代理对象已经关闭
	 * 	2、查多个存在问题,有性能的问题
	 * @param order
	 * @return
	 */
	public Order getOrder(Order order) {
		Session session = SessionFactoryUtils.openSession();
		Transaction transaction = session.beginTransaction();
		Order o = session.get(Order.class, order.getOrderId());
		if(o != null && new Integer(1).equals(order.getInitChildren())) {
			Hibernate.initialize(o.getOrderItems());
////			System.out.println(o.getOrderItems());
		}
		transaction.commit();
		session.close();
		return o;
	}
	
	public List getOrderList() {
		Session session = SessionFactoryUtils.openSession();
		Transaction transaction = session.beginTransaction();
		List list = session.createQuery("from Order").list();
		transaction.commit();
		session.close();
		return list;
	}
	
	/**
	 * z主表的数据不能随便删除,得先删除从表中对应信息,才能删除主表的信息。
	 * @param order
	 */
	public void delOrder(Order order) {
		Session session = SessionFactoryUtils.openSession();
		Transaction transaction = session.beginTransaction();
		Order order2 = session.get(Order.class, order.getOrderId());
		for (OrderItem oi : order2.getOrderItems()) {
			session.delete(oi);
		}
		session.delete(order2);
//		session.delete(order);
		transaction.commit();
		session.close();
	}
}

  1. 在核心配置文件中配置



	
		
		root
		123
		jdbc:mysql://localhost:3306/mysql?useUnicode=true&characterEncoding=UTF-8
		
		com.mysql.jdbc.Driver
		org.hibernate.dialect.MySQLDialect
        
		
		thread

		
		true
		true

		
		
		
		
		
		
		
		
		
		
	

  1. 最后开始测试demodao中的方法
package com.xfz.three.dao;

import static org.junit.Assert.*;

import java.util.List;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import com.xfz.three.entity.Order;
import com.xfz.three.entity.OrderItem;

public class DemoDaoTest {
	private DemoDao demoDao=new DemoDao();
	@Test
	public void testAddOrder() {
		Order order=new Order();
		order.setOrderNo("购物~");
		for (int i = 0; i < 6; i++) {
			OrderItem oi=new OrderItem();
			oi.setProductId(10+i);
			oi.setQuantity(20+i);
			//之前用法
//			demoDao.addOrderItem(oi);
			order.getOrderItems().add(oi);
			oi.setOrder(order);
		}
		demoDao.addOrder(order);
	}

	@Test
	public void testAddOrderItem() {
		OrderItem oi=new OrderItem();
		oi.setProductId(66);
		oi.setQuantity(66);
		Order order=new Order();
		order.setOrderId(11);
		oi.setOrder(order);
		demoDao.addOrderItem(oi);
	}

	@Test
	public void testGetOrder() {
		Order order=new Order();
		order.setOrderId(11);
		order.setInintChildren(1);
		Order o=demoDao.getOrder(order);
		//failed to lazily initialize a collection of role: 
		//com.xfz.three.entity.Order.orderItems, could not initialize proxy - no Session
		System.out.println(o.getOrderNo());
		System.out.println(o.getOrderItems().size());
	}

	@Test
	public void testGetOrderList() {
		List orderList=demoDao.getOrderList();
		for (Order order : orderList) {
			System.out.println(order.getOrderNo());
			System.out.println(order.getOrderItems().size());
		}
	}

	@Test
	public void testDelOrder() {
		Order order=new Order();
		order.setOrderId(11);
		this.demoDao.delOrder(order);
	}

}

懒加载

懒加载失败错误:

//failed to lazily initialize a collection of role: 
//com.xfz.three.entity.Order.orderItems, could not initialize proxy - no Session

解决方式:
一种是在bag标签中添加 lazy=“false” 属性。得到的结果虽然不报错但是会加载7条sql语句。弊端:性能太差,不推荐
另一种是强制加载,在订单中设置initchildren=0的字段,而0代表懒加载,1代表强制加载。在测试方法中设置initchildren为1,便可以解决问题

order.setInintChildren(1);

测试效果展示

新增的效果
hibernate一对多的关系_第1张图片
hibernate一对多的关系_第2张图片
删除后的效果
hibernate一对多的关系_第3张图片
hibernate一对多的关系_第4张图片

你可能感兴趣的:(上课内容)