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(测试类)