hibernate详解(四)---双向多对一案例

双向多对一

双向 1-n 与 双向 n-1 是完全相同的两种情形
双向 1-n 需要在 1 的一端可以访问 n 的一端, 反之依然.
域模型:从 Order 到 Customer 的多对一双向关联需要在Order 类中定义一个 Customer 属性, 而在 Customer 类中需定义存放 Order 对象的集合属性

customer类

public class Customer {
private int customerId;
private String customerName;
private Set<Order> orders=new HashSet<>();
//在定义集合属性时, 通常把它初始化为集合实现类的一个实例. 这样可以提高程序的健壮性, 避免应用程序访问取值为 null 的集合的方法抛出 NullPointerException
public Set<Order> getOrders() {
	return orders;
}
public void setOrders(Set<Order> orders) {
	this.orders = orders;
}
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;
}


}

order类

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 package="com.eduask.chp.beans">
    <class name="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>
        <!-- 映射一对多 的结合属性 -->
        <set name="orders" table="ORDERS">
        <key column="ORDER_ID"></key>
        <one-to-many class="Order"/>
        </set>
    </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>

测试:
  
	@Test
	public void testSave() {
		Customer customer=new Customer();
		Order order=new Order();
		customer.setCustomerName("张三");
		order.setOrderName("沐浴露");
		order.setCustomer(customer);
		customer.getOrders().add(order);
		session.save(customer);
		session.save(order);
		

看结果你会发现会两条insert语句 ,一句update语句
单向前一篇我们已经知道了只有两条insert语句

原因:一的一方与n方都要维护关联关系,之前的单向只有一方维护

那么如何设定他们的关联关系呢?
 在hibernate中通过对 inverse 属性的来决定是由双向关联的哪一方来维护表和表之间的关系. inverse = false 的为主动方,inverse = true 的为被动方, 由主动方负责维护关联关系
在没有设置 inverse=true 的情况下,父子两边都维护父子
  关系 
在 1-n 关系中,将 n 方设为主控方将有助于性能改善(如果要国家元首记住全国人民的名字,不是太可能,但要让全国人民知道国家元首,就容易的多)

  <set name="orders" table="ORDERS" inverse="true">

增加前面已经示例了

查:
    
@Test
	public void testGet() {
		Customer customer=(Customer) session.get(Customer.class, 1);
		System.out.println(customer.getCustomerName());
		System.out.println(customer.getOrders().getClass().getName());
		//session.close();
		//System.out.println(customer.getOrders().isEmpty());
		
	}
org.hibernate.collection.internal.PersistentSet

返回多的一端的集合是Hibernate的内置的集合类型,该类型具有延迟加载和存放代理对象的功能

    所以这里要注意懒加载问题,当session关闭的时候,想获得多的一方的信息的时候会报懒加载异常
   
改:
 
       @Test
	public void testUpdate() {
		Customer customer=(Customer) session.get(Customer.class, 1);
		customer.setCustomerName("张学友");
		customer.getOrders().iterator().next().setOrderName("羽绒服");
	}

删:
   下面代码是不可行的,涉及到级联
@Test
	public void testDelete() {
	Customer customer=(Customer) session.get(Customer.class, 1);
	customer.setCustomerId(1);
	session.delete(customer);
	}
为什么不行?
因为对象之间有关联,这个时候你就要需要设置级联.
在对象 – 关系映射文件中, 用于映射持久化类之间关联关系的元素, <set>, <many-to-one> 和 <one-to-one> 都有一个 cascade 属性, 它用于指定如何操纵与当前对象关联的其他对象. 


       <set name="orders" table="ORDERS" inverse="true" cascade="delete">


排序
<set> 元素有一个 order-by 属性, 如果设置了该属性, 当 Hibernate 通过 select 语句到数据库中检索集合对象时, 利用 order by 子句进行排序.order-by 后面跟着的是数据库表的字段名
        <set name="orders" table="ORDERS" inverse="true" cascade="delete" order-by="ORDER_ID DESC">
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值