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方法的增加(之前的实体类还有配置文件在前几天发布了)
1
// 书籍新增
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();
	}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
测试的方法,代码分享:

/**----------------------------------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 		✗
 * 相同的数据加入就会在中间表中有重复的数据,
 * 到时候在查询的时候会重复的数据
 * 
 */

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86

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

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值