zoukankan      html  css  js  c++  java
  • Hibernate多对一与一对多

     1. 多对一(多的一方是主动方)

    <many-to-one name="category" class="com.tazi.domin.Category" lazy="false" fetch="join">
         <column name="CATEGORY_ID" />
    </many-to-one>
    

     当设定fetch="join"或outer-join="true"时,在get/load时,Hibernate使用左外连接(left outer join)来查询。默认情况下,先查询主表,再根据外键查询关联表的字段值。
    例子:Product与Category(类别)是多对一的关系

    Product product=new Product();
    product.setName("台灯2");
    product.setPrice(262.3f);
    Category category=new Category();
    category.setName("生活用品");
    category.setDescription("小小的");
    product.setCategory(category);
    

     当使用session.save(product)时会报错,在未设置级联(cascade)的情况下,Hibernate不会先保存Category(一的一方)的记录,所以要先使用session.save(category)再保存product;

     2.一对多关联(多的一方为主动方)
    同样的,如果是Category(一的一方)维护关系,也需要先保存关联表才能保证正确性

    category.getProducts().add(product1);
    category.getProducts().add(product2);
    session.save(product1);//如果设置了cascade则该句和下一句不用写
    session.save(product2);
    session.save(category);
    

    Hibernate SQL语句如下:

    Hibernate: 
        insert 
        into
            hib.product
            (NAME, PRICE, DESCRIPTION) 
        values
            (?, ?, ?)
    Hibernate: 
        insert 
        into
            hib.product
            (NAME, PRICE, DESCRIPTION) 
        values
            (?, ?, ?)
    Hibernate: 
        insert 
        into
            hib.category
            (NAME, DESCRIPTION) 
        values
            (?, ?)
    Hibernate: 
        update
            hib.product 
        set
            CATEGORY_ID=? 
        where
            ID=?
    Hibernate: 
        update
            hib.product 
        set
            CATEGORY_ID=? 
        where
            ID=?
    

    注意:如果程序中交换保存的顺序,即session.save(一的一方)在先,session.save(多的一方在后),执行的结果是一样的。因为只要一的一方是主动维护关系(通过<set>与<one-to-many>),一的一方就有责任负责多的一方外键字段的更新。

     3.cascade="save-update"的作用

    它的作用仅仅是方便程序员少写几行session.save()语句,仅此而已,在提高sql语句执行效率上并没有什么作用。

            <set name="products" cascade="save-update" >
                <key>
                    <column name="CATEGORY_ID" />
                </key>
                <one-to-many class="com.tazi.domin.Product" />
            </set>
    

    此时原本需要写:session.save(多的一方)的语句现在可以不写。只要写session.save(一的一方)。

    4.理解inverse=true的作用

     <set name="products" cascade="save-update"  inverse="true"  >
                <key>
                    <column name="CATEGORY_ID" />
                </key>
                <one-to-many class="com.tazi.domin.Product" />
     </set>
    

    inverse=true意味着原本一的一方已经维护了关联关系,但现在它可以不管这些了,它保存或更新的时候可以不对多的一方负责任了。也就不会存在update外键字段这样的sql语句了。这个时候如果仍然只有一的一方维护关系(不论是在POJO中还是在映射配置文件中),那么多的一方的外键字段一定是null.此时必须让一的一方也建立关联关系,并且维护。

    		Product product=new Product();
    		product.setName("台灯2");
    		product.setPrice(262.3f);
    		
    		Product product2=new Product();
    		product2.setName("台灯3");
    		product2.setPrice(262.3f);
    		
    		Category category=new Category();
    		category.setName("生活用品");
    		category.setDescription("小小的");
    		category.getProducts().add(product);
    		category.getProducts().add(product2);
    		
    		product.setCategory(category);
    		product2.setCategory(category);
    

    同时在一的一方配置文件中:

     <many-to-one name="category" class="com.tazi.domin.Category" lazy="false" fetch="join">
                <column name="CATEGORY_ID" />
    </many-to-one> 
    

    然后session.save(category)就可以了。Hibernate执行sql的效率提高,如下:

    Hibernate: 
        insert 
        into
            hib.category
            (NAME, DESCRIPTION) 
        values
            (?, ?)
    Hibernate: 
        insert 
        into
            hib.product
            (CATEGORY_ID, NAME, PRICE, DESCRIPTION) 
        values
            (?, ?, ?, ?)
    Hibernate: 
        insert 
        into
            hib.product
            (CATEGORY_ID, NAME, PRICE, DESCRIPTION) 
        values
            (?, ?, ?, ?)
    

    这与直接由多的一方保存关联关系并维护的效果是一样的。


     

  • 相关阅读:
    Spring Boot 7:配置文件信息读取
    Spring Boot 6:自定义filter
    Spring AOP:Java动态代理和CGlib
    Spring AOP:概念
    设计模式(二)---策略模式
    设计模式(一)--装饰模式
    java并发编程实战笔记
    剑指offer java -查找旋转数组的最小数字
    读书计划
    协议初学
  • 原文地址:https://www.cnblogs.com/tazi/p/2284190.html
Copyright © 2011-2022 走看看