Hibernate(七):*.hbm.xml配置文件中Set三个属性
- 背景:
在上一篇文章中实现双向关联时,其中在Customer.java中我们使用了java.util.List<Order>来关联多的Order。其实还有另外一种实现方法:使用java.util.Set来替代java.util.List。
Customer.java(定义Order:private java.util.Set<Order> orders=new HashSet<Order>();)
1 package com.dx.hibernate.onetomany; 2 3 import java.util.HashSet; 4 import java.util.List; 5 import java.util.Set; 6 7 public class Customer { 8 private Integer customerId; 9 private String customerName; 10 private Set<Order> orders = new HashSet<Order>(); 11 12 public Customer() { 13 } 14 15 public Customer(String customerName) { 16 super(); 17 this.customerName = customerName; 18 } 19 20 public Integer getCustomerId() { 21 return customerId; 22 } 23 24 public void setCustomerId(Integer customerId) { 25 this.customerId = customerId; 26 } 27 28 public String getCustomerName() { 29 return customerName; 30 } 31 32 public void setCustomerName(String customerName) { 33 this.customerName = customerName; 34 } 35 36 public Set<Order> getOrders() { 37 return orders; 38 } 39 40 public void setOrders(Set<Order> orders) { 41 this.orders = orders; 42 } 43 }
Customer.hbm.xml
set 节点设置为:
<set name="orders" table="ORDERS" inverse="true" lazy="true"> <key> <column name="CUSTOMER_ID" /> </key> <one-to-many class="com.dx.hibernate.onetomany.Order" /> </set>
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 2017-6-1 15:27:44 by Hibernate Tools 3.5.0.Final --> 5 <hibernate-mapping> 6 <class name="com.dx.hibernate.onetomany.Customer" table="CUSTOMER"> 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 <set name="orders" table="ORDERS" inverse="false" lazy="true"> 15 <key> 16 <column name="CUSTOMER_ID" /> 17 </key> 18 <one-to-many class="com.dx.hibernate.onetomany.Order" /> 19 </set> 20 </class> 21 </hibernate-mapping>
Order.java
1 package com.dx.hibernate.onetomany; 2 3 public class Order { 4 private Integer orderId; 5 private String orderName; 6 private Customer customer; 7 8 public Order() { 9 super(); 10 } 11 12 public Order(String orderName) { 13 super(); 14 this.orderName = orderName; 15 } 16 17 public Integer getOrderId() { 18 return orderId; 19 } 20 21 public void setOrderId(Integer orderId) { 22 this.orderId = orderId; 23 } 24 25 public String getOrderName() { 26 return orderName; 27 } 28 29 public void setOrderName(String orderName) { 30 this.orderName = orderName; 31 } 32 33 public Customer getCustomer() { 34 return customer; 35 } 36 37 public void setCustomer(Customer customer) { 38 this.customer = customer; 39 } 40 41 }
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 2017-6-1 15:27:44 by Hibernate Tools 3.5.0.Final --> 5 <hibernate-mapping> 6 <class name="com.dx.hibernate.onetomany.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 name="customer" class="com.dx.hibernate.onetomany.Customer" fetch="join"> 15 <column name="CUSTOMER_ID" /> 16 </many-to-one> 17 </class> 18 </hibernate-mapping>
测试1:
1 @Test 2 public void test() { 3 Order order1 = new Order("order1"); 4 Order order2 = new Order("order2"); 5 Customer customer = new Customer("customer1"); 6 7 // 当Customer.hbm.xml中set节点属性Inverse为false时。 8 customer.getOrders().add(order1); 9 customer.getOrders().add(order2); 10 11 session.save(customer); 12 session.save(order1); 13 session.save(order2); 14 15 Customer customerFetch = (Customer) session.get(Customer.class, 1); 16 17 System.out.println(customerFetch.getCustomerName()); 18 System.out.println(customerFetch.getOrders().size()); 19 System.out.println(customerFetch.getOrders().getClass()); 20 21 }
测试通过。
在运行过程中Customer.java中Set为:class org.hibernate.collection.internal.PersistentSet,属于hibernate的一个代理对象。
session关闭,将抛出异常。
测试2:
修改Customer.hbm.xml中set节点属性inverse="true"
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 2017-6-1 15:27:44 by Hibernate Tools 3.5.0.Final --> 5 <hibernate-mapping> 6 <class name="com.dx.hibernate.onetomany.Customer" table="CUSTOMER"> 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 <set name="orders" table="ORDERS" inverse="true" lazy="true"> 15 <key> 16 <column name="CUSTOMER_ID" /> 17 </key> 18 <one-to-many class="com.dx.hibernate.onetomany.Order" /> 19 </set> 20 </class> 21 </hibernate-mapping>
测试代码:
1 @Test 2 public void test() { 3 Order order1 = new Order("order1"); 4 Order order2 = new Order("order2"); 5 Customer customer = new Customer("customer1"); 6 7 // 当Customer.hbm.xml中set节点属性inverse为false时。 8 // customer.getOrders().add(order1); 9 // customer.getOrders().add(order2); 10 11 // 当Customer.hbm.xml中set节点属性inverse为true时。 12 order1.setCustomer(customer); 13 order2.setCustomer(customer); 14 15 session.save(customer); 16 session.save(order1); 17 session.save(order2); 18 19 Customer customerFetch = (Customer) session.get(Customer.class, 1); 20 21 System.out.println(customerFetch.getCustomerName()); 22 System.out.println(customerFetch.getOrders().size()); 23 System.out.println(customerFetch.getOrders().getClass()); 24 25 }
测试通过。
接下来我们要将的是set节点的三个重要属性:inverse,cascade,order-by。
- inverse属性
1)在Hibernate中通过对inverse属性来决定是有双向关联的哪一方来维护表和表之间的关系。inverse=false为主动方,inverse=true的为被动方,由主动方负责维护关联关系。
2)在没有设置inverse=true的情况下,父子两边都维护父子关系。
3)在1-n关系中,将n方设为主控方将有助于性能改善。
- cascade属性
级联,每个Hibernate session的基本操作包括persist()、merge()、saveOrUpdate()、delete()、lock()、refresh()、evict()、replicate(),这些操作都有对应的级联风格(cascade style)。这些级联风格(cascade style)风格分别命名为persist、merge、save-update、delete、lock、refresh、evict、replicate。
级联风格 | Session中的方法 |
---|---|
persist | persist() |
merge | merge() |
save-update | save()、update()、saveOrUpdate() |
delete | delete() |
lock | lock() |
refresh | refresh() |
evict | evict() |
replicate | replicate() |
注意:
一般默认是不建议设置cascade属性。
- order-by属性
设置查询时,排序方式。
测试1:
修改Customer.hbml.xml
1 <set name="orders" table="ORDERS" inverse="true" lazy="true" cascade="save-update,delete" order-by="CUSTOMER_ID desc"> 2 <key> 3 <column name="CUSTOMER_ID" /> 4 </key> 5 <one-to-many class="com.dx.hibernate.onetomany.Order" /> 6 </set>
修改test代码:
@Test public void test() { Order order1 = new Order("order1"); Order order2 = new Order("order2"); Customer customer = new Customer("customer3"); customer.getOrders().add(order1); customer.getOrders().add(order2); order1.setCustomer(customer); order2.setCustomer(customer); session.save(customer); // session.save(order1); // session.save(order2); } @Test public void testRemoveCustomer() { Customer customer = (Customer) session.get(Customer.class, 3); session.remove(customer); }
测试通过。
基础才是编程人员应该深入研究的问题,比如:
1)List/Set/Map内部组成原理|区别
2)mysql索引存储结构&如何调优/b-tree特点、计算复杂度及影响复杂度的因素。。。
3)JVM运行组成与原理及调优
4)Java类加载器运行原理
5)Java中GC过程原理|使用的回收算法原理
6)Redis中hash一致性实现及与hash其他区别
7)Java多线程、线程池开发、管理Lock与Synchroined区别
8)Spring IOC/AOP 原理;加载过程的。。。
【+加关注】。