
hibernate的多对多
hibernate可以直接映射多对多关联关系(看作两个一对多)
下面我们拿三张表来做实例
t_book_hb
t_book_category_hb(桥接表)
t_category_hb
添加实体类及映射文件
Book
public class Book implements Serializable{
private Integer bookId;
private String bookName;
private Float price; // 一对多:一本书对应多种书本类型
private Set<Category> categroies=new HashSet<Category>(); public Set<Category> getCategroies() {
return categroies;
}
public void setCategroies(Set<Category> categroies) {
this.categroies = categroies;
}
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;
}
public Book() {
super();
} public Book(Integer bookId, String bookName, Float price) {
super();
this.bookId = bookId;
this.bookName = bookName;
this.price = price;
}
@Override
public String toString() {
return "Book [bookId=" + bookId + ", bookName=" + bookName + ", price=" + price + "]";
}
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 name="com.hmc.hibernate02.entity.Book" table="t_book_hb">
<id name="bookId" type="java.lang.Integer" column="book_id">
<!--native:identity(标识列)+sequence(序列) -->
<generator class="native"></generator>
</id>
<property name="bookName" type="java.lang.String" column="book_name"/>
<property name="price" type="java.lang.Float" column="price"/> <!--
select category_id,category_name,t_category_hb c,
t_book_category_hb bc where c.category_id=bc.cid
--> <!--建立关联关系 :一对多-->
<!--
name:实体类中定义的属性名,指向多方
cassade:用来控制如何操作关联的持久化对象的
save-update/delete/none/all
inverse:主控方
-->
<set name="categroies" cascade="save-update" inverse="true" table="t_book_category_hb" >
<!-- 对应中间表的外键列,指向一方 -->
<key column="bid"></key>
<!--指定实体之间的关联关系:一对多 -->
<!--多对多关联关系-->
<many-to-many class="com.hmc.hibernate02.entity.Category" column="cid"/>
</set>
</class> </hibernate-mapping>
Category
public class Category implements Serializable {
private Integer categoryId;
private String categoryName; //一对多:一种书本类型对应多本书
private Set<Book> books=new HashSet<Book>(); 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;
}
public Category() {
super();
}
@Override
public String toString() {
return "Category [categoryId=" + categoryId + ", categoryName=" + categoryName + ", books=" + books + "]";
}
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 name="com.hmc.hibernate02.entity.Category" table="t_category_hb">
<id name="categoryId" type="java.lang.Integer" column="category_id">
<!--native:identity(标识列)+sequence(序列) -->
<generator class="native"></generator>
</id>
<property name="categoryName" type="java.lang.String" column="category_name"/> <!--一方中的主键就是多方中的外键 -->
<!--
select book_id,book_name,price from t_book_hb b,
t_book_category_hb bc,t_book b where b.book_id=bc.bid
and bc.bid=b.book_id --> <!--建立关联关系 :一对多-->
<!--
name:实体类中定义的属性名,指向多方
cassade:用来控制如何操作关联的持久化对象的
save-update/delete/none/all
inverse:主控方
-->
<set name="books" cascade="save-update" inverse="false" table="t_book_category_hb" >
<!-- 对应中间表的外键列,指向一方 -->
<key column="cid"></key>
<!--指定实体之间的关联关系:多对多 -->
<!--class:指向的是多方的实体类的全路径名 -->
<many-to-many class="com.hmc.hibernate02.entity.Book" column="bid"/>
</set>
</class> </hibernate-mapping>
hibernate.cfg.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!--1.数据库相关 -->
<!--(connection.username|connection.password|connection.url|connection.driver_class|dialect) -->
<!--数据库账号 -->
<property name="connection.username">root</property>
<!--数据库密码 -->
<property name="connection.password">123</property>
<!--数据库连接的url -->
<!--特殊字符!!! 特殊字符!!! 特殊字符!!!-->
<property name="connection.url">
jdbc:mysql://localhost:3306/book?useUnicode=true&characterEncoding=UTF-8
</property>
<!-- 数据库连接驱动 -->
<property name="connection.driver_class">
com.mysql.jdbc.Driver
</property>
<!--数据库方言 -->
<property name="dialect">
org.hibernate.dialect.MySQLDialect
</property>
<!--2.调试相关 -->
<!--(show_sql|format_sql) -->
<property name="show_sql">true</property>
<property name="format_sql">true</property>
<!--3.实体映射相关 -->
<mapping resource="com/hmc/hibernate02/entity/Book.hbm.xml"/>
<mapping resource="com/hmc/hibernate02/entity/Category.hbm.xml"/> </session-factory>
</hibernate-configuration>
BookDao
public class BookDao { public void addBook(Book book) {
Session session = SessionFactoryUtils.openSession();
Transaction transaction = session.beginTransaction();
//保存
session.save(book);
transaction.commit();
SessionFactoryUtils.closeSession();
} public Book get(Book book) {
Session session = SessionFactoryUtils.openSession();
Transaction transaction = session.beginTransaction();
//保存
Book b = session.get(Book.class, book.getBookId());
if(b!=null) {
Hibernate.initialize(b.getCategroies());
}
transaction.commit();
SessionFactoryUtils.closeSession();
return b;
} //被控方
public void delBook(Book book) {
Session session = SessionFactoryUtils.openSession();
Transaction transaction = session.beginTransaction();
Book b = session.get(Book.class, book.getBookId());
if(null!=b) {
//解除关联关系
Set<Category> categroies = b.getCategroies();
for (Category category : categroies) {
b.getCategroies().remove(category);
}
session.delete(b);
} transaction.commit();
SessionFactoryUtils.closeSession(); }
CategoryDao
public class CategoryDao { public Category get(Category category) {
Session session = SessionFactoryUtils.openSession();
Transaction transaction = session.beginTransaction();
//保存
Category c = session.get(Category.class, category.getCategoryId());
if(c!=null) {
Hibernate.initialize(c.getBooks());
}
transaction.commit();
SessionFactoryUtils.closeSession();
return c;
} //主控方
public void delCategory(Category c) {
Session session = SessionFactoryUtils.openSession();
Transaction transaction = session.beginTransaction();
Category category = session.get(Category.class, c.getCategoryId());
if(null!=category) {
//解除关联关系
Set<Book> books = c.getBooks();
for (Book book : books) {
//错误(删除当前书本对应的书)
//category.getBooks().remove(book);
//ok(删除当前书本对应的类型)
book.getCategroies().remove(category);
}
session.delete(category);
} transaction.commit();
SessionFactoryUtils.closeSession(); }
BookDaoTest(测试类)