zoukankan      html  css  js  c++  java
  • hibernate关联关系(一对多)

    什么是关联(association)
     关联指的是类之间的引用关系。如果类A与类B关联,那么被引用的类B将被定义为类A的属性。

    案例:如何建立客户和订单一对多双向关联
     先不建立客户和订单的关联关系,定义实体及映射文件,单独执行保存操作
     建立客户到订单的一对多关联关系

    实例代码:

    Order.java:

    package com.entity;
    
    import java.util.ArrayList;
    import java.util.List;
    
    public class Order {
    
    	private Integer orderId;
    	private String orderNo;
    	
    	private List<OrderItem> OrderItems=new ArrayList<>();
    	
    	private Integer initChildren=1;//1代表开启懒加载 0则关闭
    	
     	public Integer getInitChildren() {
    		return initChildren;
    	}
    	public void setInitChildren(Integer initChildren) {
    		this.initChildren = initChildren;
    	}
    	public List<OrderItem> getOrderItems() {
    		return OrderItems;
    	}
    	public void setOrderItems(List<OrderItem> orderItems) {
    		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;
    	}
    	@Override
    	public String toString() {
    		return "Order [orderId=" + orderId + ", orderNo=" + orderNo + "]";
    	}
    	public Order(Integer orderId, String orderNo) {
    		super();
    		this.orderId = orderId;
    		this.orderNo = orderNo;
    	}
    	public Order() {
    		super();
    	}
    	
    	
    }
    

      

    OrderItem.java:

    package com.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) {
    		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 + ", Order=" + Order + "]";
    	}
    	public OrderItem(Integer orderItemId, Integer productId, Integer quantity, Integer oid) {
    		super();
    		this.orderItemId = orderItemId;
    		this.productId = productId;
    		this.quantity = quantity;
    		this.oid = oid;
    	}
    	public OrderItem() {
    		super();
    	}
    	
    	
    	
    }
    

      在同包下导入Order.hbm.xml文件以及OrderItem.hbm.xml文件

    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 name="com.entity.Order" table="t_hibernate_order">
    		<id name="orderId" type="java.lang.Integer" column="order_id">
    			<generator class="increment" />
    		</id>
    		<property name="orderNo" type="java.lang.String" column="order_no">
    		</property>
    		  <bag  name="orderItems" inverse="true"  cascade="save-update" >
    		  <!-- 从表的外键 -->
    			<key column="oid"></key>
    			<!-- 查询从表数据	 -->
    			<one-to-many class="com.entity.OrderItem" />
    		</bag>
    	</class>
    
    </hibernate-mapping>
    

      OrderItme.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 name="com.entity.OrderItem" table="t_hibernate_order_item">
    		<id name="orderItemId" type="java.lang.Integer" column="order_item_id">
    			<generator class="increment" />
    		</id>
    		<property name="productId" type="java.lang.Integer" column="product_id">
    		</property>
    		<property name="quantity" 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.entity.Order" column="oid">
    		
    		</many-to-one>
    	</class>
    </hibernate-mapping>
    

      在hibernate.hbm.xml中进行配置

    <?xml version="1.0" encoding="UTF-8"?>
    
    <!DOCTYPE hibernate-configuration PUBLIC
    	"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
    	"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
    <hibernate-configuration>
    	<session-factory>
    		<!-- 1. 数据库相关 -->
    		<property name="connection.username">root</property>
    		<property name="connection.password">123</property>
    		<property name="connection.url">jdbc:mysql://localhost:3306/mysql?useUnicode=true&characterEncoding=UTF-8
    		</property>
    		<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
    		<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
    
    		<!-- 配置本地事务(No CurrentSessionContext configured!) -->
    		<property name="hibernate.current_session_context_class">thread</property>
    
    		<!-- 2. 调试相关 -->
    		<property name="show_sql">true</property>
    		<property name="format_sql">true</property>
    
    		<!-- 3. 添加实体映射文件 -->
    			<mapping resource="com/entity/user.hbm.xml" />
    		
    	
    		<!-- 主键生成策略 -->
    		<mapping resource="com/entity/Worker.hbm.xml" />
    		<mapping resource="com/entity/Student.hbm.xml" />
    		<!-- 关联关系 -->
    		<mapping resource="com/entity/Order.hbm.xml" />
    		<mapping resource="com/entity/OrderItem.hbm.xml" />
    		
    		
    	</session-factory>
    </hibernate-configuration>
    

      DemoDao:

    package com.dao;
    
    import java.util.List;
    
    import org.hibernate.Hibernate;
    import org.hibernate.Session;
    import org.hibernate.Transaction;
    
    import com.entity.Order;
    import com.entity.OrderItem;
    import com.entity.Student;
    import com.entity.Worker;
    import com.util.SessionFactoryUtils;
    /**
     * hibernate中的主键生成策略
     * 1、人工控制
     * 2、数据库控制
     * 3、hibernate控制
     * 4、自定义主键生成策略
     * @author xyls
     *
     */
    public class DemoDao {
    /**
     * 新增学生
     * @param stu
     */
    	public void add(Student stu) {
    		Session session = SessionFactoryUtils.openSession();
    		Transaction transation=session.beginTransaction();
    		session.save(stu);
    		transation.commit();
    		SessionFactoryUtils.closeSession();
    	}
    	/**
    	 * 新增工人
    	 * @param worker
    	 */
    	public void addWorker(Worker worker) {
    		Session session = SessionFactoryUtils.openSession();
    		Transaction transation=session.beginTransaction();
    		session.save(worker);
    		transation.commit();
    		SessionFactoryUtils.closeSession();
    	}
    	/**
    	 * 
    	 * @param args
    	 */
    	public static void testStudent() {
    		DemoDao dao=new DemoDao();
    		Student stu=new Student();
    		stu.setSname("柳长歌");
    		stu.setSid(97);
    		dao.add(stu);
    	}
    	public static void main(String[] args) {
    		DemoDao dao=new DemoDao();
    		Worker worker=new Worker();
    		worker.setWname("220");
    		dao.addWorker(worker);
    		
    	}
    	/**
    	 * 为了测试关系型映射文件配置准确
    	 * 	讲解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(0).equals(order.getInitChildren())) {
    			//0代表需要强制加载关联关系对象
    			Hibernate.initialize(o.getOrderItems());
    //			System.out.println(o.getOrderItems());
    		}
    		transaction.commit();
    		session.close();
    		return o;
    	}
    	
    	public List<Order> getOrderList() {
    		Session session = SessionFactoryUtils.openSession();
    		Transaction transaction = session.beginTransaction();
    		List<Order> list = session.createQuery("from Order").list();
    		transaction.commit();
    		session.close();
    		return list;
    	}
    	
    	/**
    	 * 主表的数据不能随便删除,得先删除从表中对应信息,才能删除主表的信息。
    	 * @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();
    	}
    
    }
    

      进行测试:

    DemoDaoTest.java:

    package com.dao;
    
    import static org.junit.Assert.*;
    
    import java.util.List;
    
    import org.junit.Test;
    
    import com.entity.Order;
    import com.entity.OrderItem;
    import com.test.delDemo;
    
    public class DemoDaoTest {
    
    	private DemoDao demoDao=new DemoDao();
    	
    
    	@Test
    	public void testAddOrder() {
    		Order order=new Order();
    		order.setOrderNo("1001");
    		OrderItem oi=null;
    		for (int i = 0; i < 4; i++) {
    			oi=new OrderItem();
    			oi.setProductId(100+i);
    			oi.setQuantity(200+i);
    			oi.setOrder(order);
    			order.getOrderItems().add(oi);
    		}
    		demoDao.addOrder(order);
    //		demoDao.addOrderItem(orderItem);
    	}
    
    	@Test
    	public void testAddOrderItem() {
    		Order order=new Order();
    		order.setOrderId(5);
    		OrderItem oi=null;
    		for (int i = 0; i < 4; i++) {
    			oi=new OrderItem();
    			oi.setProductId(100+i);
    			oi.setQuantity(200+i);
    			oi.setOrder(order);
    			order.getOrderItems().add(oi);
    			demoDao.addOrderItem(oi);
    		}
    	}
    
    	@Test
    	public void testGetOrder() {
    		Order order=new Order();
    		order.setOrderId(10);
          //关闭懒加载 order.setInitChildren(0); Order o=this.demoDao.getOrder(order); System.out.println(o.getOrderNo()); System.out.println(o.getOrderItems()); } /** * 查单个需要关闭懒加载 * 查多个不能关闭懒加载 */ @Test public void testGetOrderList() { List<Order> orderList= this.demoDao.getOrderList(); for (Order order : orderList) { System.out.println(order.getOrderNo()); // System.out.println(order.getOrderItems()); } } @Test public void testDelOrder() { Order order=new Order(); order.setOrderId(9); this.demoDao.delOrder(order); } }

      

    结果:

    testAddOrder:

    Order表

    OrderItem表:

    testAddOrderItem:

    testGetOrder:

     testGetOrderList:

    testDelOrder:

    主表的oid为5的数据删除以及从表oid为5的数据也被删除

    关于hibernate的懒加载:


         如果说将懒加载的功能关闭,也就是lazy=false.那么在查询多条订单数据的情况下是非常影响性能的

    所以我在Order.java中加入:

    private Integer initChildren=1;(1代表开启懒加载 0则关闭)
    在测试类中的用法:
    关闭懒加载
    		order.setInitChildren(0);
  • 相关阅读:
    linux权限补充:rwt rwT rws rwS 特殊权限
    关于Linux操作系统下文件特殊权限的解释
    Java学习笔记——Java程序运行超时后退出或进行其他操作的实现
    Java实现 蓝桥杯 算法提高 判断名次
    Java实现 蓝桥杯 算法提高 判断名次
    Java实现 蓝桥杯 算法提高 日期计算
    Java实现 蓝桥杯 算法提高 日期计算
    Java实现 蓝桥杯 算法提高 概率计算
    Java实现 蓝桥杯 算法提高 概率计算
    Java实现 蓝桥杯 算法提高 复数四则运算
  • 原文地址:https://www.cnblogs.com/omji0030/p/11300277.html
Copyright © 2011-2022 走看看