hibernate的多对多
1.hibernate可以直接映射多对多关联关系(看作两个一对多)
多对多关系注意事项
2.1 一定要定义一个主控方
2.2 多对多删除
2.2.1 主控方直接删除
2.2.2 被控方先通过主控方解除多对多关系,再删除被控方
2.2.3 禁用级联删除
3.1关联关系编辑,不需要直接操作桥接表,hibernate的主控方会自动维 护
首先创建书本的实体类(book)和书本类型的实体类(category):
book的实体类
package com.zking.five.entity;
import java.util.HashSet;
import java.util.Set;
public class Book {
private Integer bookId;
private String bookName;
private float price;
private Set<Category> categories = new HashSet();
private Integer initcategories = 0;
public Integer getBookId() {
return bookId;
}
public void setBookId(Integer bookId) {
this.bookId = bookId;
}
public String getBookName() {
return bookName;
}
public void setBookName(String bookName) {
this.bookName = bookName;
}
public float getPrice() {
return price;
}
public void setPrice(float price) {
this.price = price;
}
public Set<Category> getCategories() {
return categories;
}
public void setCategories(Set<Category> categories) {
this.categories = categories;
}
public Integer getInitcategories() {
return initcategories;
}
public void setInitcategories(Integer initcategories) {
this.initcategories = initcategories;
}
}
category的实体类
package com.zking.five.entity;
import java.util.HashSet;
import java.util.Set;
public class Category {
private Integer categoryId;
private String categoryName;
private Set<Book> books = new HashSet();
private Integer initbooks = 0;
public Integer getCategoryId() {
return categoryId;
}
public void setCategoryId(Integer categoryId) {
this.categoryId = categoryId;
}
public String getCategoryName() {
return categoryName;
}
public void setCategoryName(String categoryName) {
this.categoryName = categoryName;
}
public Set<Book> getBooks() {
return books;
}
public void setBooks(Set<Book> books) {
this.books = books;
}
public Integer getInitbooks() {
return initbooks;
}
public void setInitbooks(Integer initbooks) {
this.initbooks = initbooks;
}
}
BookDao
package com.zking.five.dao;
import java.io.Serializable;
import org.hibernate.Hibernate;
import org.hibernate.Session;
import org.hibernate.Transaction;
import com.zking.five.entity.Book;
import com.zking.five.entity.Category;
import com.zking.four.util.SessionFactoryUtil;
public class BookDao {
public Book get(Book book) {
/**
* 新增书本
*
* @param book
* @return
*/
public Integer saveBook(Book book) {
Session session = SessionFactoryUtil.getSession();
Transaction transaction = session.beginTransaction();
Integer bid = (Integer) session.save(book);
transaction.commit();
session.close();
return bid;
}
/**
* 删除书本
*/
public void DelBook(Book book) {
Session session = SessionFactoryUtil.getSession();
Transaction transaction = session.beginTransaction();
session.delete(book);
transaction.commit();
session.close();
}
}
CategoryDao
package com.zking.five.dao;
import org.hibernate.Hibernate;
import org.hibernate.Session;
import org.hibernate.Transaction;
import com.zking.five.entity.Book;
import com.zking.five.entity.Category;
import com.zking.four.util.SessionFactoryUtil;
public class CategoryDao {
public Category get(Category category) {
/**
* 新增书本类别
* @param category
* @return
*/
public Integer saveCategory(Category category) {
Session session = SessionFactoryUtil.getSession();
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) {
Session session = SessionFactoryUtil.getSession();
Transaction transaction = session.beginTransaction();
Category c = session.get(Category.class, category.getCategoryId());
//c里面保存着与某一些书籍相关联的关系
for(Book b:c.getBooks()) {
//注意:关系交于book维护
b.getCategories().remove(c);
}
session.delete(c);
transaction.commit();
session.close();
}
}
book.hbm.xml
category.hbm.xml
注意:inverse的属性一定是相反的比如(false,true 或 true,false),谁设置了false谁就是主控方,而另一个就是被控方
测试类(新增)
/**
* 1.jdbc中的级联新增:首先填写新增数据,勾选副选框,再提交
* BookDao.add,CategoryDao.add
* hibernate:Book.add
* 有四种做法(通过设置inverse属性,有两种不可行)
* 讲解其它2种inverse属性可行的(true,false false,true)
* book.hbm.xml中的inverse为false
* Category.hbm.xml中的inverse为true
* 意思代表:主控方是book将关系(中间表)维护交给book
* (根据书本的新增而新增中间表)
* 注意一点:
* 通过管理持久态对象来操作数据库(查询一次)
*/
@Test
public void testSaveBook1() {
Book book=new Book();
book.setBookName("花非花雾非雾");
book.setPrice(12);
Category category=new Category();
category.setCategoryId(1);
book.getCategories().add(this.categoryDao.get(category));
this.bookdao.saveBook(book);
}
/**
* book.hbm.xml中的inverse为true
* Category.hbm.xml中的inverse为false
* 意思代表:主控方是Category将关系(中间表)维护交给Category
* (根据书本类型的新增而新增中间表)
* 注意一点:
* 通过管理持久态对象来操作数据库(查询一次)
*/
@Test
public void testSaveCategory() {
Category category=new Category();
category.setCategoryName("言情");
Book book=new Book();
book.setBookId(5);
category.getBooks().add(this.bookdao.get(book));
this.categoryDao.saveCategory(category);
}
/**
* book.hbm.xml中的inverse为true
* Category.hbm.xml中的inverse为ture
*出现状况:中间表无对象维护
*/
@Test
public void testSaveCategory1() {
Category category=new Category();
category.setCategoryName("言情");
Book book=new Book();
book.setBookId(5);
category.getBooks().add(this.bookdao.get(book));
this.categoryDao.saveCategory(category);
}
测试类(删除)
/**
* 讲解被控方处理中间表数据 删除
*/
@Test
public void testDel1() {
Category category=new Category();
category.setCategoryId(5);
this.categoryDao.del(category);
}
/**
* 删除主控方
* 结论:一并将从表关联的中间表信息删除
*/
@Test
public void testDel2() {
Book book=new Book();
book.setBookId(6);
this.bookdao.DelBook(book);
}
一定要主要谁是主控方,谁是被控方