一对多关联关系
- 在领域模型中, 类与类之间最普遍的关系就是关联关系.
- 以 Customer 和 Order 为例: 一个用户能发出多个订单, 而一个订单只能属于一个客户. 从 Order 到 Customer 的关联是多对一关联; 而从 Customer 到 Order 是一对多关联
单向多对一
- 单向 n-1 关联只需从 n 的一端可以访问 1 的一端
- 域模型: 从 Order 到 Customer 的多对一单向关联需要在Order 类中定义一个 Customer 属性, 而在 Customer 类中无需定义存放 Order 对象的集合属性
代码解析
Customer.java
public class Customer {
private Integer id;
private String name;
//getter 和 setter 略
}
Order.java
public class Order {
private Integer id;
private String name;
private Customer customer;
//getter 和 setter 略
}
Customer.hbm.xml
<hibernate-mapping>
<class name="com.zc.cris.n21.entity.Customer" table="CUSTOMERS">
<id name="id" type="java.lang.Integer">
<column name="CUSTOMER_ID" />
<generator class="native" />
</id>
<property name="name" type="java.lang.String">
<column name="CUSTOMER_NAME" />
</property>
</class>
</hibernate-mapping>
Order.hbm.xml
<hibernate-mapping package="com.zc.cris.n21.entity">
<!-- entity类对应的table名末尾一定要加上S,否则会莫名其妙的出错 -->
<class name="Order" table="ORDERS">
<id name="id" type="java.lang.Integer">
<column name="ORDER_ID" />
<generator class="native" />
</id>
<property name="name" type="java.lang.String">
<column name="ORDER_NAME" />
</property>
<!-- 多对一关系映射
name:表示多关联一的属性名
class:表示一对应的类名
column:表示一在多的数据表中的外键名(列名)
-->
<many-to-one name="customer" class="Customer" column="CUSTOMER_ID" foreign-key="forekey"></many-to-one>
</class>
</hibernate-mapping>
class TestHibernate2 {
private SessionFactory sessionFactory = null;
private Session session = null;
private Transaction transaction = null;
@Test
void testMany21Delete() {
Customer customer = this.session.get(Customer.class, 2);
// <!-- 特别注意hibernate 所使用的数据库方言需要进行如下设置 -->
// <property name="dialect">org.hibernate.dialect.MySQL5InnoDBDialect</property>
// <!-- hibernate 所使用的数据库方言如下,将不会创建外键,因为不能识别部分命令 -->
// <property name="dialect">org.hibernate.dialect.MySQL5Dialect</property>
//在不设置级联关系的时候,如果一还有多的引用,那么一就无法被删除
this.session.delete(customer);
}
@Test
void testMany21Get() {
//查询多默认会延迟加载一,只有使用到了一才会发送select语句进行查询一,所以获取order对象的时候,其关联的
//customer对象是一个代理对象
Order order = this.session.get(Order.class, 3);
System.out.println(order.getName());
//查询一的时候,如果session已经关了就会产生懒加载异常
this.session.close();
System.err.println(order.getCustomer().getName());
}
@Test
void testMany21Save() {
Customer customer = new Customer();
customer.setName("james");
Order order1 = new Order();
order1.setName("order1");
Order order2 = new Order();
order2.setName("order2");
//设定关联关系
order1.setCustomer(customer);
order2.setCustomer(customer);
//需要先保存一,再保存多(效率更高,否则会多出update语句,因为先插入多会无法确定外键值)
this.session.save(customer);
this.session.save(order1);
this.session.save(order2);
}
//init 和 destory 方法略
}