单向多对一
在领域模型中, 类与类之间最普遍的关系就是关联关系.
在 UML 中, 关联是有方向的.
案例:
以 Customer 和 Order 为例: 一个用户能发出多个订单, 而一个订单只能属于一个客户. 从 Order 到 Customer 的关联是多对一关联; 而从 Customer 到 Order 是一对多关联
用户类:
public class Customer {
private int customerId;
private String customerName;
public int getCustomerId() {
return customerId;
}
public void setCustomerId(int customerId) {
this.customerId = customerId;
}
public String getCustomerName() {
return customerName;
}
public void setCustomerName(String customerName) {
this.customerName = customerName;
}
}
订单类
public class Order {
private int orderId;
private String orderName;
private Customer customer;
public int getOrderId() {
return orderId;
}
public void setOrderId(int 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;
}
}
Customer.hbm.xml
<hibernate-mapping>
<class name="com.eduask.chp.beans.Customer" table="CUSTOMER">
<id name="customerId" type="int">
<column name="CUSTOMER_ID" />
<generator class="native" />
</id>
<property name="customerName" type="java.lang.String">
<column name="CUSTOMER_NAME" />
</property>
</class>
</hibernate-mapping>
Order.hbm.xml
<hibernate-mapping package="com.eduask.chp.beans" >
<class name="Order" table="ORDERS">
<id name="orderId" type="int">
<column name="ORDER_ID" />
<generator class="native" />
</id>
<property name="orderName" type="java.lang.String">
<column name="ORDER_NAME" />
</property>
<!-- 多对一映射 -->
<!--name:一的一方的名称
class:一的一方的类
column:多的一方的外键
-->
<many-to-one name="customer" class="Customer" column="CUSTOMER_ID">
</many-to-one>
</class>
</hibernate-mapping>
测试自动生成mysql表格
之前是单表的操作,现在关联表的操作有什么区别吗?
开始测试
增:
@Test
public void testSave() {
Customer customer1=new Customer();
Order order=new Order();
customer1.setCustomerName("张三");
order.setOrderName("沐浴露");
order.setCustomer(customer1);
session.save(order);
session.save(customer1);//先后保存顺序的不同有什么区别吗?
}
1.先保存用户也就是一的一端
测试结果代码:
Hibernate:
insert
into
CUSTOMER
(CUSTOMER_NAME)
values
(?)
Hibernate:
insert
into
ORDERS
(ORDER_NAME, CUSTOMER_ID)
values
(?, ?)
insert
into
CUSTOMER
(CUSTOMER_NAME)
values
(?)
Hibernate:
insert
into
ORDERS
(ORDER_NAME, CUSTOMER_ID)
values
(?, ?)
2.先保存订单也就是多的一端
测试结果代码:
Hibernate:
insert
into
ORDERS
(ORDER_NAME, CUSTOMER_ID)
values
(?, ?)
Hibernate:
insert
into
CUSTOMER
(CUSTOMER_NAME)
values
(?)
Hibernate:
update
ORDERS
set
ORDER_NAME=?,
CUSTOMER_ID=?
where
ORDER_ID=?
insert
into
ORDERS
(ORDER_NAME, CUSTOMER_ID)
values
(?, ?)
Hibernate:
insert
into
CUSTOMER
(CUSTOMER_NAME)
values
(?)
Hibernate:
update
ORDERS
set
ORDER_NAME=?,
CUSTOMER_ID=?
where
ORDER_ID=?
多出一句update语句的原因:当我们保存多的一端的时候,多的一端有外键,这个时候外键还没确定,所以最后会出现修改
所以总结下:最好先保存一的一端然后再保存多的一端
查:
@Test
public void testGet() {
Order order=(Order) session.get(Order.class, 1);
// session.close();
System.out.println(order.getCustomer().getCustomerName());
}
原因:懒加载使用的是延迟加载策略,好处就是能减少内存开销,作为懒加载的时候如果想通过代理对象查询数据库,需要在该session关闭以前才可以。你可以输出
System.out.println(order.getClass().getName());
System.out.println(order.getCustomer().getClass().getName());
前者是实体对象,后者是代理对象,所以关闭session会出现这种异常
改:
@Test
public void testUpdate() {
Order order=(Order) session.get(Order.class, 1);
order.getCustomer().setCustomerName("帅哥");
order.setOrderName("手机");
}
@Test
public void testDelete() {
//不设定级联关系的情况下,一的一端在被n的一端引用的时候不能被删除
Customer customer=new Customer();
customer.setCustomerId(1);
session.delete(customer);
}