假使有一个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双向一对一关联映射(注解版)
Hibernate关联关系配置,一对一,一对多,多对多,联合主键等的配置
NULL 博文链接:https://dreamzhong.iteye.com/blog/1200915
NULL 博文链接:https://profound-accumulation.iteye.com/blog/2243079
hibernate基于主外键的一对多/多对一关联
在hibernate中,通常配置对象关系映射关系有两种,一种是基于xml的方式,另一种是基于annotation的注解方式,熟话说,萝卜青菜,可有所爱,每个人都有自己喜欢的配置方式,我在试了这两种方式以后,发现使用...
在hibernate中,通常配置对象关系映射关系有两种,一种是基于xml的方式,另一种是基于annotation的注解方式,熟话说,萝卜青菜,可有所爱,每个人都有自己喜欢的配置方式,这个是xml配置的例子
NULL 博文链接:https://yinxiaoyong.iteye.com/blog/425782
通过联接表来建立单向一对多关联不需要描述任何物理映像,表名由以下三个部分组成:主表(ownertable)表名+从表(the other side table)表名,指向主表的外键名:主表表名+下划线+主表主键列名,指向从表的外键名:主...
实现了一对一共享主键关联,一对多,多对一,多对多关系的单项和多项两部分的关联实现,包括源码,测试代码,配置代码,工程导入即可使用,基于hibernate4.0.
Hibernate一对一数据关联 Hibernate下的多对多关系 Hibernate关系映射 Hibernate继承关系映射 Hibernate映射类型-主键生成器-核心API Hibernate3 插件Eclipse配置
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. 双向关联...
8.配置会员到订单的一对多双向关联关系 9.配置会员到留言的一对多单向关联关系 10.配置管理员到留言的一对多单向关联关系 11.配置会员到购物车的一对多单向关联关系 12.配置订单到购物车的一对一单向关联关系 13....
一对多关联(One-to-many Associations) 6.3. 高级集合映射(Advanced collection mappings) 6.3.1. 有序集合(Sorted collections) 6.3.2. 双向关联(Bidirectional associations) 6.3.3. 双向关联,涉及...
案例目录: 01 01Hibernate_Handwork : 手工配置使用Hibernate,其中详细标了Hibernate进行持久化的一些过程,因为是Hibernate的入门实例,所以注释很详细,其中有... 一对一、多对一、一对多、多对多等几种情况。
学习多对多关联关系的使用 SQL基础知识 Hibernate基础知识 1.将数据库eshopdb中的数据清空,添加初始化数据 2.运行MyEclipse,新建一个“Java Project”,加入mysql-connector-java-3.1.12-bin.jar和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各种关联模式,单向多对一,单向一对多,双向一对多,双向多对多,自身一对多关联,以及oracle,mysql的相关数据库连接配置,希望对您学习有帮助。
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. 双向关联...
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. 双向关联...