疯狂java


您现在的位置: 疯狂软件 >> 新闻资讯 >> 正文

Hibernate4.x之映射关系--单向一对多


 

在领域模型中,类与类之间最普遍的关系就是关联关系
在UML中,关联是有方向的
  以Customer和Order为例:一个用户能发出多个订单,而一个订单只能属于一个客户。从Order到Customer的关联是多对一关联;而从Customer到Order是一对多关联
 
单向n-1
  单向n-1关联只需从n的一端可以访问到1的一端
  域模型:从Order到Customer的多对一单向关联需要在Order类中定义一个Customer属性,而在Customer类中无需定义存放Order对象的集合属性
  关系数据模型:ORDER表中的CUSTOMER_ID参照CUSTOMER表的主键
 
代码如下:
 
 1 package com.yl.hibernate.entities.n21;
 2 
 3 public class Customer {
 4     
 5     private Integer customerId;
 6     private String customerName;
 7     public Integer getCustomerId() {
 8         return customerId;
 9     }
10     public void setCustomerId(Integer customerId) {
11         this.customerId = customerId;
12     }
13     public String getCustomerName() {
14         return customerName;
15     }
16     public void setCustomerName(String customerName) {
17         this.customerName = customerName;
18     }
19     
20     
21 }
 1 package com.yl.hibernate.entities.n21;
 2 
 3 public class Order {
 4     
 5     private Integer orderId;
 6     private String orderName;
 7     
 8     private Customer customer;
 9 
10     public Integer getOrderId() {
11         return orderId;
12     }
13 
14     public void setOrderId(Integer orderId) {
15         this.orderId = orderId;
16     }
17 
18     public String getOrderName() {
19         return orderName;
20     }
21 
22     public void setOrderName(String orderName) {
23         this.orderName = orderName;
24     }
25 
26     public Customer getCustomer() {
27         return customer;
28     }
29 
30     public void setCustomer(Customer customer) {
31         this.customer = customer;
32     }
33     
34     
35 }
复制代码
Customer.hbm.xml
 
复制代码
 1 <?xml version="1.0"?>
 2 <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
 3 "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
 4 <!-- Generated 2014-11-26 19:19:40 by Hibernate Tools 3.4.0.CR1 -->
 5 <hibernate-mapping>
 6     <class name="com.yl.hibernate.entities.n21.Customer" table="CUSTOMERS">
 7         <id name="customerId" type="java.lang.Integer">
 8             <column name="CUSTOMER_ID" />
 9             <generator class="native" />
10         </id>
11         <property name="customerName" type="java.lang.String">
12             <column name="CUSTOMER_NAME" />
13         </property>
14     </class>
15 </hibernate-mapping>
复制代码
Order.hbm.xml
 
复制代码
 1 <?xml version="1.0"?>
 2 <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
 3 "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
 4 <!-- Generated 2014-11-26 19:19:40 by Hibernate Tools 3.4.0.CR1 -->
 5 <hibernate-mapping>
 6     <class name="com.yl.hibernate.entities.n21.Order" table="ORDERS">
 7         <id name="orderId" type="java.lang.Integer">
 8             <column name="ORDER_ID" />
 9             <generator class="native" />
10         </id>
11         <property name="orderName" type="java.lang.String">
12             <column name="ORDER_NAME" />
13         </property>
14         <!-- 映射多对一的映射关系。使用many-to-one 来映射多对一的关联关系
15             name:多这一端关联的一那一端的属性的名字
16             class:一那一端的属性对应的类名
17             column:一那一端在多的一端对应的数据表中的外键的名字
18          -->
19         <many-to-one name="customer" class="com.yl.hibernate.entities.n21.Customer" column="CUSTOMER_ID">
20         </many-to-one>
21        
22     </class>
23 </hibernate-mapping>
复制代码
测试类:
 
复制代码
  1 package com.yl.hibernate.entities.n21;
  2 
  3 
  4 import org.hibernate.Session;
  5 import org.hibernate.SessionFactory;
  6 import org.hibernate.Transaction;
  7 import org.hibernate.cfg.Configuration;
  8 import org.hibernate.service.ServiceRegistry;
  9 import org.hibernate.service.ServiceRegistryBuilder;
 10 import org.junit.After;
 11 import org.junit.Before;
 12 import org.junit.Test;
 13 
 14 public class HibernateTest {
 15 
 16     private SessionFactory sessionFactory;
 17     private Session session;
 18     private Transaction transaction;
 19     
 20     @Before
 21     public void init() {
 22         Configuration configuration = new Configuration().configure();
 23         ServiceRegistry serviceRegistry = 
 24                 new ServiceRegistryBuilder().applySettings(configuration.getProperties())
 25                                             .buildServiceRegistry();
 26 
 27         sessionFactory = configuration.buildSessionFactory(serviceRegistry);
 28         
 29         session = sessionFactory.openSession();
 30 
 31         transaction = session.beginTransaction();
 32     }
 33     @After
 34     public void destory() {
 35         transaction.commit();
 36         
 37         session.close();
 38         
 39         sessionFactory.close();
 40     }
 41     
 42     @Test
 43     public void testMany2OneSave() {
 44         Customer customer = new Customer();
 45         customer.setCustomerName("BB");
 46         
 47         Order order1 = new Order();
 48         order1.setOrderName("ORDER-3");
 49         
 50         Order order2 = new Order();
 51         order2.setOrderName("ORDER-4");
 52         
 53         //设定关联关系
 54         order1.setCustomer(customer);
 55         order2.setCustomer(customer);
 56         
 57         //执行save操作:先插入Customer,再插入Order,3条INSERT
 58         //先插入1的一端,再插入n的一端,只有INSERT语句
 59         /*session.save(customer);
 60         
 61         session.save(order1);
 62         session.save(order2);*/
 63         
 64         //先插入Order,在插入Customer. 3条INSERT, 2条UPDATE
 65         //先插入n的一端,再插入1的一端,会多出UPDATE语句
 66         //因为在插入多的一端时,无法确定1的一端的外键值,所以只能等1的一端插入后,在额外发送UPDATE语句
 67         //推荐先插入1的一端,再插入n的一端
 68         session.save(order1);
 69         session.save(order2);
 70         
 71         session.save(customer);
 72     }
 73     
 74     @Test
 75     public void testMany2OneGet() {
 76         //1.若查询多的一端的一个对象,则默认情况下,只查询了多的一端的对象,而没有查询关联的1的那一端的对象!
 77         Order order = (Order) session.get(Order.class, 2);
 78         System.out.println(order.getOrderName());
 79         //2.在需要使用到关联的对象时,才发送对应的SQL语句
 80         Customer customer = order.getCustomer();
 81         System.out.println(customer.getCustomerName());
 82         
 83         //3.在查询Customer对象时,由多的一端导航到1的一端时,
 84         //若此时,session已被关闭,则默认情况下
 85         //会发生懒加载异常
 86         
 87         //4.获取Order对象时,默认情况下,其关联的Customer对象时一个代理对象!
 88     }
 89     
 90     @Test
 91     public void testUpdate() {
 92         Order order = (Order) session.get(Order.class, 2);
 93         order.getCustomer().setCustomerName("AAA");
 94     }
 95     
 96     @Test
 97     public void testDelete() {
 98         //在不设定级联关系的情况下,且1这一端的对象有 n 的对象在引用, 则不能直接删除1这一端的对象
 99         Customer customer = (Customer) session.get(Customer.class, 1);
100         session.delete(customer);
101     }
102     
103     
104     
105 }单向一对多