-
数据库的多对多
1.1 数据库中不能直接映射多对多
处理:创建一个桥接表(中间表),将一个多对多关系转换成两个一对多注1:数据库多表联接查询
永远就是二个表的联接查询A B C D t1 C t2 D t3
注2:交叉连接
注3:外连接:left(左)/right(右)/full(左右)
主从表:连接条件不成立时,主表记录永远保留,与null匹配A B AB select * from A,B,AB WHERE A.aID=AB.aID and b.bid = AB.bid where 在hibernate中,你只管查询当前表对象即可, hibernate会自动关联桥表以及关联表查询出关联对象 Book Category Book_category select * from Book b,Book_category bc,category where b.bid = bc.bid and bc.cid = c.cid and bid = 2
-
hibernate的多对多
2.1 hibernate可以直接映射多对多关联关系(看作两个一对多)
示例:
package com.zking.five.entity;
import java.util.HashSet;
import java.util.Set;
public class Book {
// -- 书本表
// create table t_hibernate_book
// (
// book_id int primary key auto_increment,
// book_name varchar(50) not null,
// price float not null
// );
private Integer bookId;
private String bookName;
private Float price;
private Set<Category> categories = new HashSet<>();
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;
}
}
package com.zking.five.entity;
import java.util.HashSet;
import java.util.Set;
public class Category {
// -- 书本类别表
// create table t_hibernate_category
// (
// category_id int primary key auto_increment,
// category_name varchar(50) not null
// );
// -- 桥接表
// -- 定义三个列,其实只要两个列
// -- 一个类别对应多本书,一本书对应多个类别
// create table t_hibernate_book_category
// (
// bcid int primary key auto_increment,
// bid int not null,
// cid int not null,
// foreign key(bid) references t_hibernate_book(book_id),
// foreign key(cid) references t_hibernate_category(category_id)
// );
private Integer categoryId;
private String categoryName;
private Set<Book> books = new HashSet<>();
public Set<Book> getBooks() {
return books;
}
public void setBooks(Set<Book> books) {
this.books = books;
}
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;
}
}
<?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>
<!--
1、session.get:
select * from t_hibernate_book where book_id = ?(4)
resultSet ->4 三国演义 50
2、读取book.hbm.xml文件
class name=com.zking.five.entity.Book
Book b = Class.forName(com.zking.five.entity.Book).newInstance();
while(rs.next){
<property name=bookName
->Field f = ....
f.set(b,rs.getObject(bookName));
}
->Book b里面是有值了
3、<set name=categories table=t_hibernate_book_category
select cid from t_hibernate_book_category where bid = ?(4)
3
4、根据<many-to-many class=com.zking.five.entity.Category column=cid
找到com.zking.five.entity.Category对应的映射文件category.hbm.xml
5、name=com.zking.five.entity.Category table=t_hibernate_category
select * from t_hibernate_category where categoryId = ?(3)
resultSet ->3 历史
Category c = Class.forName(com.zking.five.entity.Category).newInstance();
while(rs.next){
<property name=categoryName
->Field f = ....
f.set(c,rs.getObject(categoryName));
}
->Category c里面是有值了
-->
<class name="com.zking.five.entity.Book" table="t_hibernate_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 name="price" type="java.lang.Float" column="price"/>
<set name="categories" table="t_hibernate_book_category">
<key column="bid"></key>
<many-to-many class="com.zking.five.entity.Category" column="cid"></many-to-many>
</set>
</class>
</hibernate-mapping>
<?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 name="com.zking.five.entity.Category" table="t_hibernate_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"/>
<!--
name:指的是当前映射实体的属性
table:对应的是中间表
关联关系(中间表的数据)交于对方管理
-->
<set name="books" table="t_hibernate_book_category" cascade="save-update" inverse="true">
<!-- 指的是中间表字段(与当前映射实体对应的表的主键相关联) -->
<key column="cid"></key>
<!--
class:多方的全类名
column:中间表字段(与多方主键相关联的字段)
-->
<many-to-many class="com.zking.five.entity.Book" column="bid"></many-to-many>
</set>
</class>
</hibernate-mapping>
- 多对多关系注意事项
3.1 一定要定义一个主控方
3.2 多对多删除
3.2.1 主控方直接删除
3.2.2 被控方先通过主控方解除多对多关系,再删除被控方
3.2.3 禁用级联删除
3.3 关联关系编辑,不需要直接操作桥接表,hibernate的主控方会自动维护