数据库中不能直接映射多对多
处理:创建一个桥接表(中间表),将一个多对多关系转换成两个一对多
hibernate可以直接映射多对多关联关系(看作两个一对多)
3. 多对多关系注意事项
3.1 一定要定义一个主控方
3.2 多对多删除
3.2.1 主控方直接删除
3.2.2 被控方先通过主控方解除多对多关系,再删除被控方
3.2.3 禁用级联删除
3.3 关联关系编辑,不需要直接操作桥接表,hibernate的主控方会自动维护
案例:
数据库表:
-- 书本类别表
create table t_hibernate_category
(
category_id int primary key auto_increment,
category_name varchar(50) not null
);
-- 书本表
create table t_hibernate_book
(
book_id int primary key auto_increment,
book_name varchar(50) not null,
price float 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)
);
insert into t_hibernate_book(book_id, book_name, price) values(1,'西游记',50);
insert into t_hibernate_book(book_id, book_name, price) values(2,'红楼梦',50);
insert into t_hibernate_book(book_id, book_name, price) values(3,'水浒',50);
insert into t_hibernate_book(book_id, book_name, price) values(4,'三国演义',50);
insert into t_hibernate_category(category_id, category_name) values(1,'古典');
insert into t_hibernate_category(category_id, category_name) values(2,'神话');
insert into t_hibernate_category(category_id, category_name) values(3,'历史');
insert into t_hibernate_book_category(bid, cid) values(1,1);
insert into t_hibernate_book_category(bid, cid) values(1,2);
insert into t_hibernate_book_category(bid, cid) values(2,1);
insert into t_hibernate_book_category(bid, cid) values(3,1);
insert into t_hibernate_book_category(bid, cid) values(3,3);
insert into t_hibernate_book_category(bid, cid) values(4,1);
insert into t_hibernate_book_category(bid, cid) values(4,3);
Book.java
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> categorys = new HashSet<>();//多对多
private Integer initcategorys = 0;
public Set<Category> getCategorys() {
return categorys;
}
public void setCategorys(Set<Category> categorys) {
this.categorys = categorys;
}
public Integer getInitcategorys() {
return initcategorys;
}
public void setInitcategorys(Integer initcategorys) {
this.initcategorys = initcategorys;
}
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;
}
}
Category.java
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
// );
private Integer categoryId;
private String categoryName;
private Set<Book> books = new HashSet<>();
private Integer initbooks = 0;
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;
}
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;
}
}
用来检验所有映射的配置文件是否准确:
SessionFactoryUtils.java
package com.zking.two.util;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
/**
* 1、方便获取session会话,用来操作数据库
* 2、用来检验所有映射的配置文件是否准确
*
* @author Administrator
*
*/
public class SessionFactoryUtils {
private static SessionFactory sessionFactory;
static {
Configuration cfg = new Configuration().configure("hibernate.cfg.xml");
sessionFactory = cfg.buildSessionFactory(); //通过xml建模得到sessionfactory工厂
}
//获取session
public static Session getSession() {
Session session = sessionFactory.getCurrentSession();
if(session == null) {
session = sessionFactory.openSession();
}
return session;
}
//关闭session
public static void closeSession() {
Session session = sessionFactory.getCurrentSession();
if(session != null && session.isOpen()) {//如果打开,创建了session,就把它关闭
session.close();
}
}
public static void main(String[] args) {
Session session = SessionFactoryUtils.getSession();
session.beginTransaction();
System.out.println(session.isConnected());
SessionFactoryUtils.closeSession();
System.out.println(session.isConnected());
}
}
dao方法:
BookDao.java
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.two.util.SessionFactoryUtils;
public class BookDao {
public Book getBook(Book book) {
Session session = SessionFactoryUtils.getSession();
Transaction transaction = session.beginTransaction();
Book b = session.get(Book.class, book.getBookid());
if(b !=null && new Integer(1).equals(book.getInitcategorys()) ) {
Hibernate.initialize(b.getCategorys());
}
transaction.commit();
session.close();
return b;
}
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;
}
public void delete(Book book) {
Session session = SessionFactoryUtils.getSession();
Transaction transaction = session.beginTransaction();
session.delete(book);
transaction.commit();
session.close();
}
}
CategoryDao.java
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.two.util.SessionFactoryUtils;
public class CategoryDao {
public Category getCategory(Category category) {
Session session = SessionFactoryUtils.getSession();
Transaction transaction = session.beginTransaction();
Category c = session.get(Category.class, category.getCategoryId());
if(c !=null && new Integer(1).equals(category.getInitbooks()) ) {
Hibernate.initialize(c.getBooks());
}
transaction.commit();
session.close();
return c;
}
public Integer add(Category category) {
Session session = SessionFactoryUtils.getSession();
Transaction transaction = session.beginTransaction();
Integer cid = (Integer) session.save(category);
transaction.commit();
session.close();
return cid;
}
public void delete(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(c);
b.getCategorys().remove(c);
}
session.delete(c);
transaction.commit();
session.close();
}
}
配置:
Book.hbm.xml
Category.hbm.xml
Junit测试:
private BookDao bookDao = new BookDao();
private CategoryDao categoryDao = new CategoryDao();
@Test
public void testGetBook() {
Book book = new Book();
book.setBookid(4);
book.setInitcategorys(1);
Book b = this.bookDao.getBook(book);
System.out.println(b.getBookname());
for (Category c : b.getCategorys()) {
System.out.println(" "+c.getCategoryName());
}
}
@Test
public void testGetCategory() {
Category category = new Category();
category.setCategoryId(1);
category.setInitbooks(1);
Category c = this.categoryDao.getCategory(category);
System.out.println(c.getCategoryName());
for (Book ca : c.getBooks()) {
System.out.println(" "+ca.getBookname());
}
}
结果如下: