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

来源:互联网 发布:淘宝账号是不是会员名 编辑:程序博客网 时间:2024/06/01 08:50

双向多对一

双向 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 的集合的方法抛出 NullPointerExceptionpublic 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>

测试:
  
@Testpublic 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">

增加前面已经示例了

查:
   
@Testpublic 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关闭的时候,想获得多的一方的信息的时候会报懒加载异常
   
改:
 
       @Testpublic void testUpdate() {Customer customer=(Customer) session.get(Customer.class, 1);customer.setCustomerName("张学友");customer.getOrders().iterator().next().setOrderName("羽绒服");}

删:
   下面代码是不可行的,涉及到级联
@Testpublic 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">
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 20个月宝宝爱吃奶不爱吃饭怎么办 宝宝8个多月不肯米糊跟粥怎么办 8个月宝宝突然不肯吃米糊了怎么办 八个月宝宝突然不吃辅食怎么办 八个月宝宝拉屎费劲还干怎么办 两个月的小孩不喜欢吃奶粉怎么办 三个多月的宝宝不爱吃奶怎么办 4个月的宝宝不吃奶怎么办 九个月宝宝一直高烧不退怎么办 8个月宝宝不吃辅食怎么办 孩子七个月了母乳不够了怎么办 11个月宝宝吃的太多怎么办 宝宝十一个月了上火眼死太多怎么办 9个月孩子不吃辅食怎么办 y一夜没有睡好现在母乳不够怎么办 喂母乳的婴儿总要吃奶怎么办 宝宝四个月了奶水不够吃怎么办 宝宝出生十天了奶水不够吃怎么办 宝宝晚上不吃奶了奶水多怎么办 我家小孩六个月了奶不够吃怎么办 六个月的宝宝奶不够吃怎么办 宝贝六个月了奶不够吃怎么办 奶不够吃宝宝又不吃奶粉怎么办 婴儿到新环境哭闹不睡觉怎么办 婴儿到陌生地方狂哭不止怎么办 在家里遇到有人有陌生人敲门怎么办 在家里晚上睡觉遇到持刀小偷怎么办 在租房中房东随意调换房间怎么办 梦见熟人当面说我坏话偷东西怎么办 偷了家里的存折拿了钱该怎么办 故意让小偷偷车捉住他怎么办 进屋门正对着厕所门怎么办 楼房对面门上放个镜子我该怎么办 从顺丰发的水果坏了顺丰不管怎么办 汽车塑料件被机头水腐蚀了怎么办 孕期吃了炒菜里面加的香精怎么办 五个月宝宝只长身高不长体重怎么办 孩子6个月奶水越来越少怎么办 孩子快三个月了奶水越来越少怎么办 老婆生完孩子乳房肿胀不下奶怎么办 大人吃了退烧药不出汗怎么办