hibernate的多对多

  1. 数据库的多对多
    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
    
  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>
  1. 多对多关系注意事项
    3.1 一定要定义一个主控方
    3.2 多对多删除
    3.2.1 主控方直接删除
    3.2.2 被控方先通过主控方解除多对多关系,再删除被控方
    3.2.3 禁用级联删除
    3.3 关联关系编辑,不需要直接操作桥接表,hibernate的主控方会自动维护
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值