假使有一个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);