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);

 

你可能感兴趣的:(Hibernate)