1数据库中的多对多关系:
1-1: 数据库中不能直接映射多对多
处理:创建一个桥接表(中间表),将一个多对多关系转换成两个一对多
注1:数据库多表联接查询
永远就是二个表的联接查询
注2:交叉连接
注3:外连接:left(左)/right(右)/full(左右)
主从表:连接条件不成立时,主表记录永远保留,与null匹配
2. hibernate的多对多
2.1 hibernate可以直接映射多对多关联关系(看作两个一对多)
3、实例:
3-1:创建一个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<Category>();
// 强制初始化
public Integer initCategories = 0 ;
public Integer getInitCategories() {
return initCategories;
}
public void setInitCategories(Integer initCategories) {
this.initCategories = initCategories;
}
public Set<Category> getCategories() {
return categories;
}
public void setCategories(Set<Category> categories) {
this.categories = categories;
}
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;
}
}
xml配置:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class table="t_hibernate_book" name="com.zking.five.entity.Book">
<id name="bookId" type="java.lang.Integer" column="book_id">
<generator class="increment"></generator>
</id>
<property name="bookName" type="java.lang.String" column="book_name"></property>
<property name="price" type="java.lang.Float" column="price"></property>
<set table="t_hibernate_book_category" name="categories" cascade="save-update" inverse="false">
<!-- one 的关系 -->
<key column="bid"></key>
<many-to-many column="cid" class="com.zking.five.entity.Category"></many-to-many>
</set>
</class>
</hibernate-mapping>
3-2:创建一个类别实体类: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<Book>();
private Integer initBooks = 0 ;
public Integer getInitBooks() {
return initBooks;
}
public void setInitBooks(Integer initBooks) {
this.initBooks = initBooks;
}
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;
}
}
xml配置:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class table="t_hibernate_category" name="com.zking.five.entity.Category">
<id name="categoryId" type="java.lang.Integer" column="category_id">
<generator class="increment"></generator>
</id>
<property name="categoryName" type="java.lang.String" column="category_name"></property>
<set table="t_hibernate_book_category" name="books" cascade="save-update" inverse="true">
<key column="cid"></key>
<many-to-many column="bid" class="com.zking.five.entity.Book"></many-to-many>
</set>
</class>
</hibernate-mapping>
3-3:增加:
public Integer add(Book book) {
Session session = SessionFactoryUtils.getSession();
Transaction transaction = session.beginTransaction();
Integer bid = (Integer)session.save(book);
transaction.commit();
session.close();
return bid;
}
@Test
public void testAdd1() {
Book book = new Book();
book.setBookName("不温不火");
book.setPrice(23f);
Category category = new Category();
category.setCategoryId(5);
book.getCategories().add(this.CategoryDao.get(category));
this.bookDao.add(book);
}
3-4:删除:
/**
* 删除
* @param book
*/
public void del(Book book) {
Session session = SessionFactoryUtils.getSession();
Transaction transaction = session.beginTransaction();
session.delete(book);
transaction.commit();
session.close();
}
/**
* 主控方删除
* 需求:删除有关联的一本书
* 删除,不温不火的这本书,
* 同时删除中间表
*/
@Test
public void testDel() {
Book book = new Book();
book.setBookId(5);
this.bookDao.del(book);
}
/**
* 删除
* 1、被控方通过主控方来解除关联的关系
* 2、再去删除被控方
* @param book
*/
public void del(Category category) {
Session session = SessionFactoryUtils.getSession();
Transaction transaction = session.beginTransaction();
Category c = session.get(Category.class, category.getCategoryId());
for(Book b : c.getBooks()) {
// c.getBooks().remove(b);
b.getCategories().remove(c);
}
session.delete(c);
transaction.commit();
session.close();
}
/**
* 被控方删除
* 需求:删除有关联关系的一个类别,包括该类别下的所有书籍
* 结果:无法删除
* Cannot delete or update a parent row: a foreign key constraint fails (`test`.`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(5);
this.CategoryDao.del(category);
}