Hibernate 筆記二(多表設計之一對多)

Hibernate 多表設計之一對多


示例:用戶表和訂單表關係爲一對多的關係,一個用戶可以有多個訂單,但是一個訂單隻能對應一個用戶


  • Customer.java
    在“一”的一方(Customer)用Set來保存所有訂單引用
public class Customer {
    private Integer id;
    private String name;

    private Set<Order> orders = new HashSet<>();
    // Get和Set 代碼略過
}
  • Order.java
    直接保存Customer 的引用
public class Order {

    private Integer id;
    private String orderName;

    private Customer customer;
    // Get和Set 代碼略過
}
  • ORM 映射文件表達一對多關係、多對一

    用set節點來描述一對多

<set name="orders" inverse="false">
            <key column="cid"></key>
            <one-to-many class="Order"/>
        </set>

key節點用來描述外鍵列名,one-to-many 指定引用Customer作爲外鍵的表所對應用java Bean 類 ,Set 中的Inverse 屬性代表“是否不維護外鍵”True 替表不維護,False 代表維護,只能在“一”的一方放棄維護


Customer.hbm.xml

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE hibernate-mapping PUBLIC 
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

<hibernate-mapping package="com.longdenghui.one2many2">
    <class name="Customer" table="t_customer">
        <id name="id" column="id">
            <generator class="native"></generator>
        </id>

        <property name="name" column="name"></property>

        <set name="orders" inverse="false">
            <key column="cid"></key>
            <one-to-many class="Order"/>
        </set>
    </class>
</hibernate-mapping>

Order.hbm.xml 中使用

<many-to-one name="customer" column="cid"></many-to-one>

來描述多對一的關係


Order.hbm.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC 
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

<hibernate-mapping package="com.longdenghui.one2many2">

    <class name="Order" table="t_order">

        <id name="id" column="id">
            <generator class="native"></generator>
        </id>

        <property name="orderName" column="order_name"></property>

        <many-to-one name="customer" column="cid"></many-to-one>
    </class>
</hibernate-mapping>

測試

        Configuration conf = new Configuration().configure();

        Session session = conf.buildSessionFactory().openSession();

        Transaction tr = session.beginTransaction();

        Customer c1 = new Customer();
        c1.setName("龍登輝");

        Order o1 = new Order();
        Order o2 = new Order();

        o1.setOrderName("娃哈哈");
        o2.setOrderName("洗衣粉");

//      o1.setCustomer(c1);
//      o2.setCustomer(c1);

        c1.getOrders().add(o1);
        c1.getOrders().add(o2);

        session.save(c1);
        session.save(o1);
        session.save(o2);
        tr.commit();

因爲在Cusotmer.hbm.xml 中寫了Inverse 屬性爲False 所以Customer 會維護外鍵,不用再寫下列兩行代碼

        o1.setCustomer(c1);
        o2.setCustomer(c1);

如是inverse 屬性爲False 爲True 則代表Customer 放棄維護外鍵,所以上列兩行代碼必須加上,不然在Order表中的外鍵就爲null了,

  • cascade 屬性(save-update | delete | delete-orphan | all | all-delete-orphan

    級聯保存或更新 使用cascade屬性值選用“save-update”在Order 表中保存 Cutomer 表的主鍵,所以刪Customer 表需要先刪除Order 表中的數據,而在Customer.hbm.xml 文件中設置了級聯刪除的話可以使用以下代碼直接刪除

Customer c = (Customer) session.get(Customer.class, 1);

session.delete(c);
  1. save-update(級聯保存或更新)

    在“多”的一方中保存或更新“一”的一方的引用時,Hibernate 會幫我們將這些變化同步到數據庫中。

  2. delete-orphan 孤兒刪除
    在“多“的一方中刪除所保存的“一”的一方的引用時,代表和Order表所對應的數據解除關係,Order 表中被解除關係的數據被稱爲孤兒,Hibernate 會自動將孤兒數據刪除。

  3. delete 級聯刪除
    當調用session中的delete() 方法 ,想要刪除一個Customer(“一”的一方)對象時,Hibernate 會將“多”的一方保存的引用所對應的數據庫的數據刪除。

  4. all : save-update 和 delete 整合

  5. all-delete-orphan : 三個整合

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章