Hibernate 映射关联关系
Hibernate 映射关联关系 一、映射多对一关联关系。
1.单向的多对一
(1)以 Customer 和 Order 为例:一个用户可以发出多个订单,而一个订单只能属于一个客户。从 Order 到 Customer 是多对一关联关系。
(2)创建 Customer 和 Order 表。 Create
(3)用 Intellij Idea 自动生成关联关系,以及对应的 Entitiy.hbm.xml 和 持久化类。 说明:
其中 Type 是用来修饰对应的 Attribute Name 的。
在 Order 端,定义 Customer 类,一个订单属于一个客户。而在 Customer 端,一个客户可以有多个订单,因为是单向的,所以这里放弃属性的添加。
在 Join Columns 定义了 Order 和 Customer 之间的关联关系,order 表中的 customer_id 外键和 customer 表中的 customer_id 主键关联。
来看生成的 Schema:
没有勾选 customer_id,是因为 Intellij Idea 没法直接映射为 Customer 类型的 customer。
Order.hbm.xml
使用
name 属性:多这一端关联的一那一端的属性的名称。
class 属性:关联的一端的属性的类型。
column 属性:一那一端在多的一端对应的数据表中的外键。可以任意命名,但需要和数据表中的字段对应。
(4)单向多对一的 CRUD 以及需要注意的问题。 <1> 新增
Hibernate 映射关联关系
①先保存一的一端 Customer,后保存多的一端 Order。
Save.java 打印 SQL: Output
结论:发送了3条 INSERT 语句。
②先保存多的一端 Order,再保存一的一端 Customer。
Save2.java 打印 SQL: Output2
结论:发送了3条 INSERT 语句,2条 UPDATE 语句。
总结:在单向多对一的关联关系下,先插入 1 的一端会减少 SQL 语句的执行,性能更高。 <2>删除
先删除1的一端。
Delete.java 控制台打印:
Cannot delete or update a parent row: a foreign key constraint fails (`hibernate`.`order`, CONSTRAINT `FK_m6q2ofkj1g5aobtb2p00ajpqg` FOREIGN KEY (`customer_id`) REFERENCES `customer` (`customer_id`))
结论:在不设置级联关系的前提下,不能删除 1 的一端。 <3>更新
Update.java Output <4>查询
①查询 n 的一端,但是不使用查询出来关联的 1 的一端的对象。 @Test
public void testMany2OneGet() {
Order order = (Order) session.get(Order.class, 1);
System.out.println(order.getCustomer().getClass().getName()); } 复制代码
Hibernate 映射关联关系
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
hibernate.order order0_ where
order0_.order_id=? order1
com.nucsoft.hibernate.Customer_$$_jvst30c_1 复制代码
②查询 n 的一端,使用查询出来关联的 1 的一端的对象。 @Test
public void testMany2OneGet() {
Order order = (Order) session.get(Order.class, 1);
System.out.println(order.getCustomer().getClass().getName()); 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
hibernate.order order0_ where
order0_.order_id=?
com.nucsoft.hibernate.Customer_$$_jvst30c_1 Hibernate: select
customer0_.customer_id as customer1_0_0_, customer0_.customer_name as customer2_0_0_ from
hibernate.customer customer0_ where
customer0_.customer_id=? 复制代码
总结:可以发现,采用的是懒加载机制,即获取到的 1 的一端的对象是一个代理对象。只有在使用这个对象的属性的情况下,才会发送 SQL 语句。
③ 由懒加载机制引发的 懒加载异常。