1. 程式人生 > >hibernate的多對多的關聯 2(增加、刪除)

hibernate的多對多的關聯 2(增加、刪除)

重點:

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);
	}