Hibernate雙向一對多映射關係(2)

來源:互聯網
上載者:User

標籤:一對多   --   節點   nes   key   setting   service   元素   hbm   

雙向 1-n 與 雙向 n-1 是完全相同的兩種情形

雙向 1-n 需要在 1 的一端可以訪問 n 的一端, 反之依然.

領域模型:從 Order 到 Customer 的多對一雙向關聯需要在Order 類中定義一個 Customer 屬性, 而在 Customer 類中需定義存放 Order 對象的集合屬性

關係資料模型:ORDERS 表中的 CUSTOMER_ID 參照 CUSTOMER 表的主鍵

            

Customer.java

private Integer customerId;    private String customerName;    private Set<Order> orders = new HashSet<>();

1. 聲明集合類型時, 需使用介面類型, 因為 hibernate 在擷取
  集合類型時, 返回的是 Hibernate 內建的集合類型, 而不是 JavaSE 一個標準的
  集合實現.
2. 需要把集合進行初始化, 可以防止發生null 指標異常


Order.java

private Integer orderId;private String orderName;    private Customer customer;

Customer.hbm.xml

<set name="orders" table="ORDERS" inverse="true" order-by="ORDER_NAME DESC">            <!-- 執行多的表中的外鍵列的名字 -->        <key column="CUSTOMER_ID"></key>        <!-- 指定映射類型 -->       <one-to-many class="Order"/> </set>

<!-- 映射 一 對多的那個集合屬性 -->
<!-- set: 映射 set 類型的屬性, table: set 中的元素對應的記錄放在哪一個資料表中. 該值需要和多對一的多的那個表的名字一致 -->
<!-- inverse: 指定由哪一方來維護關聯關係. 通常設定為 true, 以指定由多的一端來維護關聯關係 -->
<!-- cascade 設定級聯操作. 開發時不建議設定該屬性. 建議使用手工的方式來處理 -->
<!-- order-by 在查詢時對集合中的元素進行排序, order-by 中使用的是表的欄位名, 而不是持久化類的屬性名稱 -->

Order.java

<many-to-one name="customer" class="Customer" column="CUSTOMER_ID"></many-to-one>

 HibernateTest.java

public class HibernateTest {    private SessionFactory sessionFactory;    private Session session;    private Transaction transaction;        @Before    public void init(){        Configuration configuration = new Configuration().configure();        ServiceRegistry serviceRegistry =                 new ServiceRegistryBuilder().applySettings(configuration.getProperties())                                            .buildServiceRegistry();        sessionFactory = configuration.buildSessionFactory(serviceRegistry);                session = sessionFactory.openSession();        transaction = session.beginTransaction();    }        @After    public void destroy(){        transaction.commit();        session.close();        sessionFactory.close();    }        @Test    public void testCascade(){        Customer customer = (Customer) session.get(Customer.class, 3);        customer.getOrders().clear();    }        @Test    public void testDelete(){        //在不設定級聯關係的情況下, 且 1 這一端的對象有 n 的對象在引用, 不能直接刪除 1 這一端的對象        Customer customer = (Customer) session.get(Customer.class, 1);        session.delete(customer);     }        @Test    public void testUpdat2(){        Customer customer = (Customer) session.get(Customer.class, 1);        customer.getOrders().iterator().next().setOrderName("GGG");     }        @Test    public void testUpdate(){        Order order = (Order) session.get(Order.class, 1);        order.getCustomer().setCustomerName("AAA");    }        @Test    public void testOne2ManyGet(){        //1. 對 n 的一端的集合使用消極式載入        Customer customer = (Customer) session.get(Customer.class, 7);        System.out.println(customer.getCustomerName());         //2. 返回的多的一端的集合時 Hibernate 內建的集合類型.         //該類型具有消極式載入和存放代理對象的功能.         System.out.println(customer.getOrders().getClass());         //session.close();        //3. 可能會拋出 LazyInitializationException 異常                 System.out.println(customer.getOrders().size());                 //4. 再需要使用集合中元素的時候進行初始化.     }        @Test    public void testMany2OneGet(){        //1. 若查詢多的一端的一個對象, 則預設情況下, 只查詢了多的一端的對象. 而沒有查詢關聯的        //1 的那一端的對象!        Order order = (Order) session.get(Order.class, 1);        System.out.println(order.getOrderName());                 System.out.println(order.getCustomer().getClass().getName());                session.close();                //2. 在需要使用到關聯的對象時, 才發送對應的 SQL 陳述式.         Customer customer = order.getCustomer();        System.out.println(customer.getCustomerName());                 //3. 在查詢 Customer 對象時, 由多的一端導航到 1 的一端時,         //若此時 session 已被關閉, 則預設情況下        //會發生 LazyInitializationException 異常                //4. 擷取 Order 對象時, 預設情況下, 其關聯的 Customer 對象是一個代理對象!            }        @Test    public void testMany2OneSave(){        Customer customer = new Customer();        customer.setCustomerName("AA");                Order order1 = new Order();        order1.setOrderName("ORDER-1");                Order order2 = new Order();        order2.setOrderName("ORDER-2");                //設定關聯關係        order1.setCustomer(customer);        order2.setCustomer(customer);                customer.getOrders().add(order1);        customer.getOrders().add(order2);                //執行  save 操作: 先插入 Customer, 再插入 Order, 3 條 INSERT, 2 條 UPDATE        //因為 1 的一端和 n 的一端都維護關聯關係. 所以會多出 UPDATE        //可以在 1 的一端的 set 節點指定 inverse=true, 來使 1 的一端放棄維護關聯關係!        //建議設定 set 的 inverse=true, 建議先插入 1 的一端, 後插入多的一端        //好處是不會多出 UPDATE 語句        session.save(customer);        //        session.save(order1);//        session.save(order2);                //先插入 Order, 再插入 Cusomer, 3 條 INSERT, 4 條 UPDATE//        session.save(order1);//        session.save(order2);//        //        session.save(customer);    }}

 

Hibernate雙向一對多映射關係(2)

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.