hibernate的多對多的關聯 2(增加、刪除)
阿新 • • 發佈:2018-10-31
重點:
1、級聯新增 inverse屬性值的設定
2、 級聯刪除
重點解析:
1.hibernate的多對多
1.1 hibernate可以直接對映多對多關聯關係(看作兩個一對多)
講解inverse;
總共四種 (false 是控制方 ,true 是被控制方),其中有兩種正確,兩種錯誤
- 1、book:false category:true ✓(代表意思是:將維護的責任交給book)
- 2、book: true category:false ✓
- 3、book:true category:true ✗
- 4、book:false category:false ✗
多對多關係注意事項
2.1 一定要定義一個主控方
2.2 多對多刪除
2.2.1 主控方直接刪除
2.2.2 被控方先通過主控方解除多對多關係,再刪除被控方
2.2.3 禁用級聯刪除
2.3 關聯關係編輯,不需要直接操作橋接表,hibernate的主控方會自動維護
這是是dao方法的增加(之前的實體類還有配置檔案在前幾天釋出了)
// 書籍新增 public Integer add(Book book) { Configuration configure = new Configuration().configure("hibernate.cfg.xml"); SessionFactory sessionFactory = configure.buildSessionFactory(); Session session = sessionFactory.openSession(); Transaction transaction = session.beginTransaction(); Integer bid = (Integer) session.save(book); transaction.commit(); session.close(); return bid; } //書籍刪除 public void del(Book book) { Configuration configure = new Configuration().configure("hibernate.cfg.xml"); SessionFactory sessionFactory = configure.buildSessionFactory(); Session session = sessionFactory.openSession(); Transaction transaction = session.beginTransaction(); session.delete(book); transaction.commit(); session.close(); } // 書籍型別 新增 public Integer save(Category category) { Configuration configure = new Configuration().configure("hibernate.cfg.xml"); SessionFactory sessionFactory = configure.buildSessionFactory(); Session session = sessionFactory.openSession(); Transaction transaction = session.beginTransaction(); Integer cid = (Integer) session.save(category); transaction.commit(); session.close(); return cid; } /** * 因為被控方被中間表所引用 * 1、觸發關聯關係(主控方解除多對多關係) * 2、刪除主控方的相關資料 * * @param category */ // 書籍型別刪除 public void del(Category category) { Configuration configure = new Configuration().configure("hibernate.cfg.xml"); SessionFactory sessionFactory = configure.buildSessionFactory(); Session session = sessionFactory.openSession(); Transaction transaction = session.beginTransaction(); Category c = session.get(Category.class, category.getCategoryId()); //c 裡面儲存著與某一些書籍相關聯的關係 for (Book b : c.getBooks()) { //注意:關係交於book維護 // c.getBooks().remove(b); 這是錯誤的 b.getCategories().remove(c); } session.delete(c); transaction.commit(); session.close(); }
測試的方法,程式碼分享:
/**----------------------------------six--------------------------- *- 提交書本資訊,勾選複選框類別, 提交 * jdbc: bookDao.add,bookCategoryDao.add * hibernate : bookDao.add * * 講解inverse; * 總共四種 (false 是控制方 ,true 是被控制方),其中有兩種正確,兩種錯誤 * 1、book:false category:true ✓(代表意思是:將維護的責任交給book) * 2、book: true category:false ✓ * 3、book:true category:true ✗ * 4、book:false category:false ✗ */ /*錯誤1: * Caused by: com.mysql.jdbc.exceptions. * jdbc4.MySQLIntegrityConstraintViolationException: * Column 'category_name' cannot be null * * 解決方法:這個錯誤是沒有把物件持久態,所以才會出現這個問題把物件通過get方法獲取物件持久態就沒問題了 * * */ /** * 注意: * hibernate 通過管理持久態物件來操作資料庫 */ @Test public void testAdd() { /** * 1、book:false category:true ✓(代表意思是:將維護的責任交給book) */ Book book = new Book(); book.setBookName("顫抖吧!ET"); book.setPrice(66F); //這是錯誤的示範 Category category = new Category(); category.setCategoryId(4); book.getCategories().add(category); //要通過get獲取持久態物件 /*Category category = new Category(); category.setCategoryId(4); book.getCategories().add(this.categoryDao.get(category));*/ this.bookDao.add(book); } /* * 在新增類別的時候不能用第一種維護關係,必須所以第二種,因為(將關係(中間表)維護的責任交給book)) * 2、book: true category:false ✓ * */ @Test public void testAdd2() { Category category = new Category(); category.setCategoryName("穿越"); Book book = new Book(); book.setBookId(4); category.getBooks().add(this.bookDao.get(book)); this.categoryDao.save(category); } /** * 3、book:true category:true ✗ * 出現錯誤:中間表無物件維護(類別新增但是中間沒有資料) */ @Test public void testAdd3() { Category category = new Category(); category.setCategoryName("言情"); Book book = new Book(); book.setBookId(5); category.getBooks().add(this.bookDao.get(book)); this.categoryDao.save(category); } /** * 4、book:false category:false ✗ * 相同的資料加入就會在中間表中有重複的資料, * 到時候在查詢的時候會重複的資料 * */
/**------------------del----------------------
* 多對多刪除
* 1 、主控方直接刪除
* 2、 被控方先通過主控方解除多對多關係,再刪除被控方
*/
/*
* 主控方直接刪除
* 結論: 一併將從表關聯的中間表資訊刪除
*/
@Test
public void testDel() {
Book book = new Book();
book.setBookId(5);
this.bookDao.del(book);
}
/*
* 被控方先通過主控方解除多對多關係,再刪除被控方
*/
/**
* 錯誤2:
* Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException:
* Cannot delete or update a parent row: a foreign key constraint fails
* (`mybatis_ssm`.`t_hibernate_book_category`, CONSTRAINT `t_hibernate_book_category_ibfk_2`
* FOREIGN KEY (`cid`) REFERENCES `t_hibernate_category` (`category_id`))
*
* 解決方法:
* 這是報資料庫的主外來鍵連線的錯誤,如果你有刪除的外來鍵表的資料就要先刪除主鍵表的資料
*/
@Test
public void testDel2() {
Category category = new Category();
category.setCategoryId(1);
this.categoryDao.del(category);
}