`

hibernate一对多关联关系配置经验

 
阅读更多

假使有一个order表和一个customer表,那么它们两者的关系是一个customer可以有多个order,一个order只能属于一个customer,在hibernate中,他们的配置如下:

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping
PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping >

  <class name="mypack.Customer" table="CUSTOMERS" >
    <id name="id" type="long" column="ID">
      <generator class="increment"/>
    </id>

    <property name="name" type="string" >
        <column name="NAME" length="15" />
    </property>
<!--

    <set 
        name="orders"
        cascade="all-delete-orphan" 
        inverse="true"
         >
        
        <key column="CUSTOMER_ID" />
        <one-to-many class="mypack.Order" />
     </set>   
-->
    <set 
        name="orders"
        inverse="true"
        cascade="save-update" 
        >
        
        <key column="CUSTOMER_ID" />
        <one-to-many class="mypack.Order" />
     </set>   

  </class>
</hibernate-mapping>

 

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping
PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping >

   <class name="mypack.Order" table="ORDERS">
     
      <id name="id" type="long" column="ID">
        <generator class="increment"/>
      </id>
   
      <property name="orderNumber" type="string" >
        <column name="ORDER_NUMBER" length="15" />
      </property>
      
      <many-to-one
        name="customer"
        column="CUSTOMER_ID"
        class="mypack.Customer"
        cascade="save-update"
       />

    </class>
 
</hibernate-mapping>

 

他们的业务类中则有以下方法:

package mypack;

import org.hibernate.*;
import org.hibernate.cfg.Configuration;
import java.util.*;

public class BusinessService{
  public static SessionFactory sessionFactory;
  private Long idOfTom;
  private Long idOfTomOrder;
  private Long idOfJack;
  private Long idOfJackOrder;

  static{
     try{
       Configuration config = new Configuration();
       config.configure();
       sessionFactory = config.buildSessionFactory();
    }catch(RuntimeException e){e.printStackTrace();throw e;}
  }

  public void printOrdersOfCustomer(Long customerId){
    Session session = sessionFactory.openSession();
    Transaction tx = null;
    try {
      tx = session.beginTransaction();
      Customer customer=(Customer)session.get(Customer.class,customerId);
      printOrders(customer.getOrders());
      tx.commit();
    }catch (RuntimeException e) {
      if (tx != null) {
         tx.rollback();
      }
      throw e;
    } finally {
       session.close();
    }
  }

  public void saveCustomerAndOrderWithCascade(){
    Session session = sessionFactory.openSession();
    Transaction tx = null;
    try {
      tx = session.beginTransaction();

      Customer customer=new Customer("Tom",new HashSet());
      Order order=new Order();
      order.setOrderNumber("Tom_Order001");

      order.setCustomer(customer);
      customer.getOrders().add(order);

      session.save(customer);
      tx.commit();
      idOfTom=customer.getId();
      idOfTomOrder=order.getId();  
                  
    }catch (RuntimeException e) {
      if (tx != null) {
        tx.rollback();
      }
      e.printStackTrace();
    } finally {
      session.close();
    }
  }

    public void associateCustomerAndOrder(){
    Session session = sessionFactory.openSession();
    Transaction tx = null;
    try {
      tx = session.beginTransaction();
      Customer customer=(Customer)session.load(Customer.class,idOfJack);
      Order order=(Order)session.load(Order.class,idOfJackOrder);
      order.setCustomer(customer);
      customer.getOrders().add(order);
      tx.commit();
    }catch (RuntimeException e) {
      if (tx != null) {
        tx.rollback();
      }
       e.printStackTrace();
    } finally {
      session.close();
    }
  }

  public void saveCustomerAndOrderSeparately(){
    Session session = sessionFactory.openSession();
    Transaction tx = null;
    try {
      tx = session.beginTransaction();

      Customer customer=new Customer();
      customer.setName("Jack");

      Order order=new Order();
      order.setOrderNumber("Jack_Order001");

      session.save(customer);
      session.save(order);
      
      tx.commit();
      idOfJack=customer.getId();
      idOfJackOrder=order.getId(); 
    }catch (RuntimeException e) {
      if (tx != null) {
        tx.rollback();
      }
       e.printStackTrace();
    } finally {
      session.close();
    }
  }

  public void deleteCustomer(Long customerId){
    Session session = sessionFactory.openSession();
    Transaction tx = null;
    try {
      tx = session.beginTransaction();
      Customer customer=(Customer)session.load(Customer.class,customerId);
      session.delete(customer);
      tx.commit();

    }catch (RuntimeException e) {
      if (tx != null) {
        tx.rollback();
      }
       e.printStackTrace();
    } finally {
      session.close();
    }
  }

  public void removeOrderFromCustomer(Long customerId){
    Session session = sessionFactory.openSession();
    Transaction tx = null;
    try {
      tx = session.beginTransaction();
      Customer customer=(Customer)session.load(Customer.class,customerId);
      Order order=(Order)customer.getOrders().iterator().next();

      //½â³ýCustomerºÍOrderµÄ¹ØÁª¹Øϵ
      customer.getOrders().remove(order);
      order.setCustomer(null);
      tx.commit();

    }catch (RuntimeException e) {
      if (tx != null) {
        tx.rollback();
      }
       e.printStackTrace();
    } finally {
      session.close();
    }
  }

  public void printOrders(Set orders){
      for (Iterator it = orders.iterator(); it.hasNext();) {
         Order order=(Order)it.next();
         System.out.println("OrderNumber of "+order.getCustomer().getName()+ " :"+order.getOrderNumber());
      }
  }

   public void saveCustomerAndOrderWithInverse(){
      saveCustomerAndOrderSeparately();
      associateCustomerAndOrder();
   }
   public void test(){

      saveCustomerAndOrderWithCascade();
      saveCustomerAndOrderWithInverse();
      printOrdersOfCustomer(idOfTom);
      deleteCustomer(idOfJack);
      removeOrderFromCustomer(idOfTom);
  }

  public static void main(String args[]){
    new BusinessService().test();
    sessionFactory.close();
  }
}

 

由以上代码执行时的效率和打印的sql语句,我们可以得出以下经验:1.应把one的一方的<set>元素的inverse属性,设置为true,因此hibernate不会因为customer对象的属性变化来同步更新数据库,以提高性能。  2.在建立关联关系之后,在进行更新操作的时候,最好操作关联两端的对象的相关属性。如:

order.setCustomer(customer);
customer.getOrders().add(order);

 这样会是程序更加健壮,提高业务逻辑的独立性,使代码不收hibernate实现的影像。同理,当解除双向关联关系时,也该操作关联双发的对应属性,如:

customer.getOrders().remove(order);
order.setCustomer(null);

 

0
2
分享到:
评论
3 楼 diaozhanming 2013-05-03  
bewithme 写道
实际中都基本不用XML配,都用注解,而且基本用JPA。
现在用注解是肯定的,但是jpa的话,现在基本还是都用hibernate的实现,hibernate还是很有用武之地。
2 楼 hellostory 2013-05-02  
为什么网上除了DEMO还是DEMO,真正能解决实际项目开发的没见过,哎!
1 楼 bewithme 2013-05-02  
实际中都基本不用XML配,都用注解,而且基本用JPA。

相关推荐

    Hibernate双向一对一关联映射(注解版)

    Hibernate双向一对一关联映射(注解版)

    Hibernate关联关系配置

    Hibernate关联关系配置,一对一,一对多,多对多,联合主键等的配置

    Hibernate ORM - 一对多双向关联关系

    NULL 博文链接:https://dreamzhong.iteye.com/blog/1200915

    Hibernate一对多关联映射(注解)

    NULL 博文链接:https://profound-accumulation.iteye.com/blog/2243079

    hibernate基于主外键的一对多/多对一关联

    hibernate基于主外键的一对多/多对一关联

    Hibernate1对多1对1多对多关联映射例子源码含注解配置

    在hibernate中,通常配置对象关系映射关系有两种,一种是基于xml的方式,另一种是基于annotation的注解方式,熟话说,萝卜青菜,可有所爱,每个人都有自己喜欢的配置方式,我在试了这两种方式以后,发现使用...

    Hibernate1对多1对1多对多关联映射例子源码含xml配置

    在hibernate中,通常配置对象关系映射关系有两种,一种是基于xml的方式,另一种是基于annotation的注解方式,熟话说,萝卜青菜,可有所爱,每个人都有自己喜欢的配置方式,这个是xml配置的例子

    hibernate 多对一映射关联配置

    NULL 博文链接:https://yinxiaoyong.iteye.com/blog/425782

    Hibernate_Annotation关联映射

    通过联接表来建立单向一对多关联不需要描述任何物理映像,表名由以下三个部分组成:主表(ownertable)表名+从表(the other side table)表名,指向主表的外键名:主表表名+下划线+主表主键列名,指向从表的外键名:主...

    hibernate实现数据库表的多种关系

    实现了一对一共享主键关联,一对多,多对一,多对多关系的单项和多项两部分的关联实现,包括源码,测试代码,配置代码,工程导入即可使用,基于hibernate4.0.

    Hibernate学习资料(java)

    Hibernate一对一数据关联 Hibernate下的多对多关系 Hibernate关系映射 Hibernate继承关系映射 Hibernate映射类型-主键生成器-核心API Hibernate3 插件Eclipse配置

    Hibernate_3.2.0_符合Java习惯的关系数据库持久化

    6.2.5. 一对多关联(One-to-many Associations) 6.3. 高级集合映射(Advanced collection mappings) 6.3.1. 有序集合(Sorted collections) 6.3.2. 双向关联(Bidirectional associations) 6.3.3. 双向关联...

    eshop1.0(ssh电子商城)

    8.配置会员到订单的一对多双向关联关系 9.配置会员到留言的一对多单向关联关系 10.配置管理员到留言的一对多单向关联关系 11.配置会员到购物车的一对多单向关联关系 12.配置订单到购物车的一对一单向关联关系 13....

    hibernate 体系结构与配置 参考文档(html)

    一对多关联(One-to-many Associations) 6.3. 高级集合映射(Advanced collection mappings) 6.3.1. 有序集合(Sorted collections) 6.3.2. 双向关联(Bidirectional associations) 6.3.3. 双向关联,涉及...

    Hibernate3.1_学习源码

    案例目录: 01 01Hibernate_Handwork : 手工配置使用Hibernate,其中详细标了Hibernate进行持久化的一些过程,因为是Hibernate的入门实例,所以注释很详细,其中有... 一对一、多对一、一对多、多对多等几种情况。

    多对多关联关系的使用

    学习多对多关联关系的使用 SQL基础知识 Hibernate基础知识 1.将数据库eshopdb中的数据清空,添加初始化数据 2.运行MyEclipse,新建一个“Java Project”,加入mysql-connector-java-3.1.12-bin.jar和Hibernate类库...

    Hibernate+中文文档

    6.2.5. 一对多关联(One-to-many Associations) 6.3. 高级集合映射(Advanced collection mappings) 6.3.1. 有序集合(Sorted collections) 6.3.2. 双向关联(Bidirectional associations) 6.3.3. 双向关联...

    hibernate配置文件

    该文档总结了hibernate各种关联模式,单向多对一,单向一对多,双向一对多,双向多对多,自身一对多关联,以及oracle,mysql的相关数据库连接配置,希望对您学习有帮助。

    HibernateAPI中文版.chm

    6.2.5. 一对多关联(One-to-many Associations) 6.3. 高级集合映射(Advanced collection mappings) 6.3.1. 有序集合(Sorted collections) 6.3.2. 双向关联(Bidirectional associations) 6.3.3. 双向关联...

    hibernate3.2中文文档(chm格式)

    6.2.5. 一对多关联(One-to-many Associations) 6.3. 高级集合映射(Advanced collection mappings) 6.3.1. 有序集合(Sorted collections) 6.3.2. 双向关联(Bidirectional associations) 6.3.3. 双向关联...

Global site tag (gtag.js) - Google Analytics