在领域模型中,类与类之间最普通的关系就是关联关系。
在UML中,关联是有方向的:
例如:Customer与Order,一个用户能发出多个订单,而一个订单只能属于一个用户。
- 单向关联
1)从Order到Customer的关联是多对一关联;
定义Customer:
1 package com.dx.hibernate.onetomany; 2 3 public class Customer { 4 private Integer customerId; 5 private String customerName; 6 7 public Customer() { 8 } 9 10 public Customer(String customerName) { 11 super(); 12 this.customerName = customerName; 13 } 14 15 public Integer getCustomerId() { 16 return customerId; 17 } 18 19 public void setCustomerId(Integer customerId) { 20 this.customerId = customerId; 21 } 22 23 public String getCustomerName() { 24 return customerName; 25 } 26 27 public void setCustomerName(String customerName) { 28 this.customerName = customerName; 29 } 30 }
<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <!-- Generated 2017-5-24 12:02:56 by Hibernate Tools 3.5.0.Final --> <hibernate-mapping> <class name="com.dx.hibernate.onetomany.Customer" table="CUSTOMER"> <id name="customerId" type="java.lang.Integer"> <column name="CUSTOMER_ID" /> <generator class="native" /> </id> <property name="customerName" type="java.lang.String"> <column name="CUSTOMER_NAME" /> </property> </class> </hibernate-mapping>
定义Order:
package com.dx.hibernate.onetomany; public class Order { private Integer orderId; private String orderName; private Customer customer; public Integer getOrderId() { return orderId; } public void setOrderId(Integer orderId) { this.orderId = orderId; } public String getOrderName() { return orderName; } public void setOrderName(String orderName) { this.orderName = orderName; } public Customer getCustomer() { return customer; } public void setCustomer(Customer customer) { this.customer = customer; } }
<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <!-- Generated 2017-5-24 12:02:56 by Hibernate Tools 3.5.0.Final --> <hibernate-mapping> <class name="com.dx.hibernate.onetomany.Order" table="ORDERS"> <id name="orderId" type="java.lang.Integer"> <column name="ORDER_ID" /> <generator class="assigned" /> </id> <property name="orderName" type="java.lang.String"> <column name="ORDER_NAME" /> </property> <many-to-one name="customer" class="com.dx.hibernate.onetomany.Customer"> <column name="CUSTOMER_ID" /> </many-to-one> </class> </hibernate-mapping>
初始化项目时,生成sql语句:
Hibernate: create table CUSTOMER ( CUSTOMER_ID integer not null auto_increment, CUSTOMER_NAME varchar(255), primary key (CUSTOMER_ID) ) engine=InnoDB Hibernate: create table ORDERS ( ORDER_ID integer not null auto_increment, ORDER_NAME varchar(255), CUSTOMER_ID integer, primary key (ORDER_ID) ) engine=InnoDB Hibernate: alter table ORDERS add constraint FKkdbly1ij6f4kqh378kfne6ilx foreign key (CUSTOMER_ID) references CUSTOMER (CUSTOMER_ID)
测试代码1:
package com.dx.hibernate.onetomany; import static org.junit.Assert.fail; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.Transaction; import org.hibernate.boot.Metadata; import org.hibernate.boot.MetadataSources; import org.hibernate.boot.model.naming.ImplicitNamingStrategyComponentPathImpl; import org.hibernate.boot.registry.StandardServiceRegistry; import org.hibernate.boot.registry.StandardServiceRegistryBuilder; import org.junit.After; import org.junit.Before; import org.junit.Test; public class TestMain { private SessionFactory sessionFactory = null; private Session session = null; private Transaction transaction = null; @Before public void init() { StandardServiceRegistry standardRegistry = new StandardServiceRegistryBuilder().configure().build(); Metadata metadata = new MetadataSources(standardRegistry).getMetadataBuilder().applyImplicitNamingStrategy(ImplicitNamingStrategyComponentPathImpl.INSTANCE).build(); sessionFactory = metadata.getSessionFactoryBuilder().build(); session = sessionFactory.getCurrentSession(); transaction = session.beginTransaction(); } @Test public void test() { Customer customer = new Customer("customer1"); Order order1 = new Order("order1", customer); Order order2 = new Order("order2", customer); session.save(customer); session.save(order1); session.save(order2); } @After public void destory() { transaction.commit(); session.close(); sessionFactory.close(); } }
测试执行sql:
Hibernate: insert into CUSTOMER (CUSTOMER_NAME) values (?) Hibernate: insert into ORDERS (ORDER_NAME, CUSTOMER_ID) values (?, ?) Hibernate: insert into ORDERS (ORDER_NAME, CUSTOMER_ID) values (?, ?)
测试代码2:
@Test public void test() { Order order = (Order) session.get(Order.class, 1); System.out.println(order.getOrderName()); System.out.println(order.getCustomer().getCustomerName()); }
测试结果:
测试通过,且查询语句为:
Hibernate: select order0_.ORDER_ID as ORDER_ID1_1_0_, order0_.ORDER_NAME as ORDER_NA2_1_0_, order0_.CUSTOMER_ID as CUSTOMER3_1_0_ from ORDERS order0_ where order0_.ORDER_ID=? order1 Hibernate: select customer0_.CUSTOMER_ID as CUSTOMER1_0_0_, customer0_.CUSTOMER_NAME as CUSTOMER2_0_0_ from CUSTOMER customer0_ where customer0_.CUSTOMER_ID=? customer1
测试代码3:
@Test public void test() { Order order = (Order) session.get(Order.class, 1); System.out.println(order.getOrderName()); //System.out.println(order.getCustomer().getCustomerName()); session.close(); System.out.println(order.getCustomer().getCustomerName()); }
测试结果不通过,执行sql语句:
Hibernate: select order0_.ORDER_ID as ORDER_ID1_1_0_, order0_.ORDER_NAME as ORDER_NA2_1_0_, order0_.CUSTOMER_ID as CUSTOMER3_1_0_ from ORDERS order0_ where order0_.ORDER_ID=? order1
测试4:
修改Order.hbm.xml
<many-to-one name="customer" class="com.dx.hibernate.onetomany.Customer" fetch="join"> <column name="CUSTOMER_ID" /> </many-to-one>
测试代码:
Order order = (Order) session.get(Order.class, 1);
System.out.println(order.getOrderName());
System.out.println(order.getCustomer().getCustomerName());
测试通过,打印的sql语句:
Hibernate: select order0_.ORDER_ID as ORDER_ID1_1_0_, order0_.ORDER_NAME as ORDER_NA2_1_0_, order0_.CUSTOMER_ID as CUSTOMER3_1_0_, customer1_.CUSTOMER_ID as CUSTOMER1_0_1_, customer1_.CUSTOMER_NAME as CUSTOMER2_0_1_ from ORDERS order0_ left outer join CUSTOMER customer1_ on order0_.CUSTOMER_ID=customer1_.CUSTOMER_ID where order0_.ORDER_ID=?
测试代码5:
修改Order.hbm.xml
<many-to-one name="customer" class="com.dx.hibernate.onetomany.Customer" fetch="join"> <column name="CUSTOMER_ID" /> </many-to-one>
测试代码:
Order order = (Order) session.get(Order.class, 1); System.out.println(order.getOrderName()); System.out.println(order.getCustomer().getCustomerName()); session.close(); System.out.println(order.getCustomer().getCustomerName());
测试不通过。
2)从Customer到Order的关联是一对多关联。
Order.java
1 package com.dx.hibernate.onetomany; 2 3 public class Order { 4 private Integer orderId; 5 private String orderName; 6 7 public Order() { 8 super(); 9 } 10 11 public Order(String orderName) { 12 super(); 13 this.orderName = orderName; 14 } 15 16 public Integer getOrderId() { 17 return orderId; 18 } 19 20 public void setOrderId(Integer orderId) { 21 this.orderId = orderId; 22 } 23 24 public String getOrderName() { 25 return orderName; 26 } 27 28 public void setOrderName(String orderName) { 29 this.orderName = orderName; 30 } 31 32 }