由于数据库中不能直接映射多对多关系,处理方式为创建一个桥接表(中间表),将一个多对多关系转换成两个一对多,所以以书籍和书籍类别为例来讲解Hibernate关联映射中的多对多关联关系。
数据库设计:
(1) t_hibernate_book
(2) t_hibernate_book_category
(3) t_hibernate_category
Book实体类(提供set&get方法)
> 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> categorys=new HashSet<Category>();//书籍类别,表示一本书可属于多个类别
> private Integer initCategorys=0;//用于判断是否需要懒加载,0懒加载,1立即加载
Book.hbm.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 name="categorys" cascade="save-update" inverse="false" table="t_hibernate_book_category">
<key column="bid"></key>
Category实体类(提供set&get方法)
> 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;//用于判断是否需要懒加载,0懒加载,1立即加载
Category.hbm.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 name="books" cascade="save-update" inverse="true" table="t_hibernate_book_category">
<key column="cid"></key>
<many-to-many column="bid" class="com.zking.five.entity.Book"></many-to-many> </set> </class>
</hibernate-mapping>
根据书本id查询单个:
> public Book get(Book book) {
Session session = SessionFactoryUtil.getSession();//获取session
Transaction transaction = session.beginTransaction();//开启事务
Book b = session.get(Book.class, book.getBookId());//查询
if(b!=null&&new Integer(1).equals(book.getInitCategorys())){//如果book.getInitCategorys()为1则立即加载
> Hibernate.initialize(b.getCategorys());//设为立即加载
}
> transaction.commit();//提交事务
> SessionFactoryUtil.closeSession();//关闭session
return b;
}
> @Test
public void testGet1() {
Book book=new Book();
> book.setBookId(4);//查询书本ID为4的书本
book.setInitCategorys(1);//立即加载
> Book b = this.get(book);
> System.out.println("书名:"+b.getBookName());
for (Category cg :b.getCategorys()) {
> System.out.println("所属类别:"+cg.getCategoryName());
}
}
根据类别i单个查询
public class CategoryDao {
public Category get(Category category) {
Session session = SessionFactoryUtil.getSession();
Transaction transaction = session.beginTransaction();
Category cg = session.get(Category.class, category.getCategoryId());
if(cg!=null&&new Integer(1).equals(category.getInitBooks())) {
Hibernate.initialize(cg.getBooks());
}
transaction.commit();
SessionFactoryUtil.closeSession();
return cg;
}
@Test
public void testGet2() {
Category category=new Category();
category.setCategoryId(3);
category.setInitBooks(1);
Category cg = this.get(category);
System.out.println("类别名:"+cg.getCategoryName());
for (Book b : cg.getBooks()) {
System.out.println("该类别下的书本:"+b.getBookName());
}
}
}
多对多关系注意事项:
1、一定要定义一个主控方,即配置文件里inverse属性要一个为true一个为false
2、多对多删除:
a、主控方直接删除
b 、被控方先通过主控方解除多对多关系,再删除被控方
c、禁用级联删除