• 背景:

  在上一篇文章中实现双向关联时,其中在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>();)

 package com.dx.hibernate.onetomany;

 import java.util.HashSet;
import java.util.List;
import java.util.Set; public class Customer {
private Integer customerId;
private String customerName;
private Set<Order> orders = new HashSet<Order>(); public Customer() {
} public Customer(String customerName) {
super();
this.customerName = customerName;
} public Integer getCustomerId() {
return customerId;
} public void setCustomerId(Integer customerId) {
this.customerId = customerId;
} public String getCustomerName() {
return customerName;
} public void setCustomerName(String customerName) {
this.customerName = customerName;
} public Set<Order> getOrders() {
return orders;
} public void setOrders(Set<Order> orders) {
this.orders = orders;
}
}

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>
 <?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-6-1 15:27:44 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>
<set name="orders" table="ORDERS" inverse="false" lazy="true">
<key>
<column name="CUSTOMER_ID" />
</key>
<one-to-many class="com.dx.hibernate.onetomany.Order" />
</set>
</class>
</hibernate-mapping>

Order.java

 package com.dx.hibernate.onetomany;

 public class Order {
private Integer orderId;
private String orderName;
private Customer customer; public Order() {
super();
} public Order(String orderName) {
super();
this.orderName = orderName;
} 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;
} }

Order.hbm.xml

 <?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-6-1 15:27:44 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="native" />
</id>
<property name="orderName" type="java.lang.String">
<column name="ORDER_NAME" />
</property>
<many-to-one name="customer" class="com.dx.hibernate.onetomany.Customer" fetch="join">
<column name="CUSTOMER_ID" />
</many-to-one>
</class>
</hibernate-mapping>

测试1:

 @Test
public void test() {
Order order1 = new Order("order1");
Order order2 = new Order("order2");
Customer customer = new Customer("customer1"); // 当Customer.hbm.xml中set节点属性Inverse为false时。
customer.getOrders().add(order1);
customer.getOrders().add(order2); session.save(customer);
session.save(order1);
session.save(order2); Customer customerFetch = (Customer) session.get(Customer.class, 1); System.out.println(customerFetch.getCustomerName());
System.out.println(customerFetch.getOrders().size());
System.out.println(customerFetch.getOrders().getClass()); }

测试通过。

在运行过程中Customer.java中Set为:class org.hibernate.collection.internal.PersistentSet,属于hibernate的一个代理对象。

session关闭,将抛出异常。

测试2:

修改Customer.hbm.xml中set节点属性inverse="true"

 <?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-6-1 15:27:44 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>
<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>
</class>
</hibernate-mapping>

测试代码:

     @Test
public void test() {
Order order1 = new Order("order1");
Order order2 = new Order("order2");
Customer customer = new Customer("customer1"); // 当Customer.hbm.xml中set节点属性inverse为false时。
// customer.getOrders().add(order1);
// customer.getOrders().add(order2); // 当Customer.hbm.xml中set节点属性inverse为true时。
order1.setCustomer(customer);
order2.setCustomer(customer); session.save(customer);
session.save(order1);
session.save(order2); Customer customerFetch = (Customer) session.get(Customer.class, 1); System.out.println(customerFetch.getCustomerName());
System.out.println(customerFetch.getOrders().size());
System.out.println(customerFetch.getOrders().getClass()); }

测试通过。

接下来我们要将的是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

         <set name="orders" table="ORDERS" inverse="true" lazy="true" cascade="save-update,delete" order-by="CUSTOMER_ID desc">
<key>
<column name="CUSTOMER_ID" />
</key>
<one-to-many class="com.dx.hibernate.onetomany.Order" />
</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);
}

测试通过。

Hibernate(七):*.hbm.xml配置文件中Set三个属性的更多相关文章

  1. hibernate(*.hbm.xml)中新添加的字段被标记为红色(找不到)的解决方法

    首先得是以这个方式生成的bean和xml,配置好了数据源(这样才能让hibernate中的配置和mysql进行交互) https://www.cnblogs.com/kinome/p/10549969 ...

  2. hibernate.cfg.xml配置文件和hbm.xml配置文件

    http://blog.sina.com.cn/s/blog_a7b8ab2801014m0e.html hibernate.cfg.xml配置文件格式 <?xml version=" ...

  3. hibernate.cfg.xml配置文件和hbm.xml配置文件 模板

    hibernate.cfg.xml配置文件格式 <?xml version="1.0" encoding="UTF-8"?><!DOCTYPE ...

  4. 通过java程序调用ant build.xml配置文件中指定的target

    一.概述 通过ant实现项目的自动化部署,jar包生成,替换,tomcat关停.启动,查看项目日志: 通过java程序调用已编辑好的ant脚本build.xml配置文件中指定的target: 文中文件 ...

  5. @Required 注释应用于 bean 属性的 setter 方法,它表明受影响的 bean 属性在配置时必须放在 XML 配置文件中,否则容器就会抛出一个 BeanInitializationException 异常。

    @Required 注释应用于 bean 属性的 setter 方法,它表明受影响的 bean 属性在配置时必须放在 XML 配置文件中,否则容器就会抛出一个 BeanInitializationEx ...

  6. Spring的xml配置文件中约束的必要性 找不到元素 'beans' 的声明

    今天在复习Spring MVC框架的时候,只知道xml配置文件中的约束有规范书写格式的作用,所以在配置HandlerMapping对象信息的时候没有加入约束信息之后进行测试,没有遇到问题.后来在配置S ...

  7. mybatis 中的 xml 配置文件中 ‘<’、 ‘>’ 处理

    mybatis 中的 xml 配置文件中 '<'. '>' 处理 1.使用转义字符将 '<'. '>' 替换掉. 描述 字符 转义字符 小于号 < < 大于号 &g ...

  8. web.xml配置文件中<async-supported>true</async-supported>报错

    web.xml配置文件中<async-supported>true</async-supported>报错 http://blog.csdn.net/dream_ll/arti ...

  9. struts2配置文件中action的name属性

    struts2配置文件中action的name属性的第一个字符不要加斜杠 <action name="see" class="baoxiuManage_seeAct ...

随机推荐

  1. 戴尔R720xd服务器系统安装

    型号:R720xd 开启服务器,Ctrl+R进入raid配置 配置完raid后F2对硬盘进行格式化 保存并重启 F11进入BIOS选项设置U盘启动 选择U盘启动 开始进行系统安装!

  2. 原生js实现简单的全屏滚动

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  3. [Oracle] UNIX与Windows 2000上Oracle的差异(II)

    作者:Ian Adam & David Stien, SAIC Ltd 日期:19-Dec-2003 出处:http://www.dbanotes.net翻译:Fenng 数据库启动与关闭 在 ...

  4. Python进阶_面对对象&面对过程

    这节主要讲面对对象与面对过程两种编程思想的主要区别. 一. 简单对比 面向过程是一种基础的方法,它考虑的是实际的实现步骤,一般情况下,面向过程是自顶向下逐步求精,其最重要的是模块化的思想方法. 面向对 ...

  5. JS基础二

    JS的实现: 核心:ECMAScript ECMAScript 并不与任何具体浏览器相绑定,实际上,它也没有提到用于任何用户输入输出的方法(这点与 C 这类语言不同,它需要依赖外部的库来完成这类任务) ...

  6. 用js编解码base64

    以下是编码和解码的方法 function Base64() { // private property _keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdef ...

  7. 警示:AL32UTF8字符集不是ZHS16GBK字符集的超集

    今天有一个客户向我咨询:数据库由ZHS16GBK字符集修改为AL32UTF8字符集,发现中文的数据中小部分出现乱码,客户认为AL32UTF8明明可以支持更多的文字,不应该出现这样的情况才对. 从现象看 ...

  8. MyEclipse安装Eclipse Memory Analyzer插件以及使用例子

    一 :安装 1.Memory Analyzer 插件下载地址:http://www.eclipse.org/mat/downloads.php 2.将下载的文件解压到MyEclipse的  dropi ...

  9. [bzoj1601]灌水_kruskal

    灌水 bzoj-1601 题目大意:给你n块地,将两块地之间连通有代价$P_{i,j}$,单独在一块地打井需要代价$C_i$,问将所有的井都有水的代价是多少. 注释:1<=n<=300. ...

  10. JAVA字符串缓存器全部方法功能及其作用

    不知道干嘛的 serialVersionUID 构造一个没有字符的字符串缓冲区,初始容量为16个字符. StringBuffer() 构造一个没有字符的字符串缓冲区和指定的初始容量. StringBu ...