hibernate的多对多
hibernate可以直接映射多对多关联关系(看作两个一对多
多对多关系注意事项
一定要定义一个主控方
多对多删除
主控方直接删除
被控方先通过主控方解除多对多关系,再删除被控方
禁用级联删除
关联关系编辑,不需要直接操作桥接表,hibernate的主控方会自动维护
一对多的自关联
映射文件TreeNode.hbm.xml
1 <?xml version="1.0" encoding="UTF-8"?> 2 <!DOCTYPE hibernate-mapping PUBLIC 3 "-//Hibernate/Hibernate Mapping DTD 3.0//EN" 4 "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> 5 <hibernate-mapping> 6 <class name="com.MavenHibernate.four.entity.TreeNode" table="t_hibernate_sys_tree_node"> 7 <id name="nodeId" type="java.lang.Integer" column="tree_node_id"> 8 <generator class="increment" /> 9 </id> 10 <property name="nodeName" type="java.lang.String" 11 column="tree_node_name"> 12 </property> 13 <property name="treeNodeType" type="java.lang.Integer" 14 column="tree_node_type"> 15 </property> 16 <property name="position" type="java.lang.Integer" 17 column="position"> 18 </property> 19 <property name="url" type="java.lang.String" 20 column="url"> 21 </property> 22 23 <many-to-one name="parent" class="com.MavenHidernate.four.entity.TreeNode" column="parent_node_id"/> 24 25 <set name="children" cascade="save-update" inverse="true"> 26 <key column="parent_node_id"></key> 27 <one-to-many class="com.MavenHidernate.four.entity.TreeNode"/> 28 </set> 29 </class> 30 </hibernate-mapping>
映射文件TreeNode.hbm.xml对应的实体类TreeNode.java
1 package com.MavenHidernate.four.entity; 2 3 import java.util.HashSet; 4 import java.util.Set; 5 6 public class TreeNode { 7 private Integer nodeId; 8 private String nodeName; 9 private Integer treeNodeType; 10 private Integer position; 11 private String url; 12 private TreeNode parent; 13 private Set<TreeNode> children = new HashSet<TreeNode>(); 14 private Integer initChildren = 0; 15 16 public Integer getNodeId() { 17 return nodeId; 18 } 19 20 public void setNodeId(Integer nodeId) { 21 this.nodeId = nodeId; 22 } 23 24 public String getNodeName() { 25 return nodeName; 26 } 27 28 public void setNodeName(String nodeName) { 29 this.nodeName = nodeName; 30 } 31 32 public Integer getTreeNodeType() { 33 return treeNodeType; 34 } 35 36 public void setTreeNodeType(Integer treeNodeType) { 37 this.treeNodeType = treeNodeType; 38 } 39 40 public Integer getPosition() { 41 return position; 42 } 43 44 public void setPosition(Integer position) { 45 this.position = position; 46 } 47 48 public String getUrl() { 49 return url; 50 } 51 52 public void setUrl(String url) { 53 this.url = url; 54 } 55 56 public TreeNode getParent() { 57 return parent; 58 } 59 60 public void setParent(TreeNode parent) { 61 this.parent = parent; 62 } 63 64 public Set<TreeNode> getChildren() { 65 return children; 66 } 67 68 public void setChildren(Set<TreeNode> children) { 69 this.children = children; 70 } 71 72 public Integer getInitChildren() { 73 return initChildren; 74 } 75 76 public void setInitChildren(Integer initChildren) { 77 this.initChildren = initChildren; 78 } 79 80 // @Override 81 // public String toString() { 82 // return "TreeNode [nodeId=" + nodeId + ", nodeName=" + nodeName + ", treeNodeType=" + treeNodeType 83 // + ", position=" + position + ", url=" + url + ", children=" + children + "]"; 84 // } 85 86 @Override 87 public String toString() { 88 return "TreeNode [nodeId=" + nodeId + ", nodeName=" + nodeName + ", treeNodeType=" + treeNodeType 89 + ", position=" + position + ", url=" + url + ", parent=" + parent + ", children=" + children 90 + ", initChildren=" + initChildren + "]"; 91 } 92 93 94 }
TreeNodeDao方法
1 package com.MavenHibernate.four.dao; 2 3 import org.hibernate.Hibernate; 4 import org.hibernate.Session; 5 import org.hibernate.Transaction; 6 7 import com.MavenHibernate.two.util.SessionFactoryUtils; 8 import com.MavenHibernate.four.entity.TreeNode; 9 10 public class TreeNodeDao { 11 public TreeNode load(TreeNode treeNode) { 12 Session session = SessionFactoryUtils.openSession(); 13 Transaction transaction = session.beginTransaction(); 14 TreeNode treenode = session.load(TreeNode.class, treeNode.getNodeId()); 15 if(treenode != null && new Integer(1).equals(treeNode.getInitChildren())) { 16 Hibernate.initialize(t.getChildren()); 17 Hibernate.initialize(t.getParent()); 18 } 19 transaction.commit(); 20 session.close(); 21 return treenode; 22 } 23 }
junit测试TreeNodeDao
TreeNodeDaoTest
1 package com.MavenHibernate.four.dao; 2 3 import org.junit.Test; 4 5 import com.MavenHibernate.four.entity.TreeNode; 6 7 public class TreeNodeDaoTest { 8 private TreeNodeDao treeNodeDao = new TreeNodeDao(); 9 10 @Test 11 public void testLoad() { 12 TreeNode treeNode = new TreeNode(); 13 treeNode.setNodeId(6); 14 treeNode.setInitChildren(1); 15 16 TreeNode t = this.treeNodeDao.load(treeNode); 17 System.out.println(t); 18 System.out.println(t.getParent()); 19 System.out.println(t.getChildren()); 20 } 21 22 }
多对多关联关系
映射文件category.hbm.xml
1 <?xml version="1.0" encoding="UTF-8"?> 2 <!DOCTYPE hibernate-mapping PUBLIC 3 "-//Hibernate/Hibernate Mapping DTD 3.0//EN" 4 "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> 5 <hibernate-mapping> 6 <class name="com.MavenHibernate.four.entity.Category" table="t_hibernate_category"> 7 <id name="categoryId" type="java.lang.Integer" column="category_id"> 8 <generator class="increment" /> 9 </id> 10 <property name="categoryName" type="java.lang.String" 11 column="category_name"> 12 </property> 13 14 <set table="t_hibernate_book_category" name="books" cascade="save-update" inverse="true"> 15 <key column="cid"></key> 16 <many-to-many column="bid" class="com.MavenHibernate.four.entity.Book"></many-to-many> 17 </set> 18 </class> 19 </hibernate-mapping>
映射文件category.hbm.xml对应的实体类category
1 package com.MavenHibernate.four.entity; 2 3 import java.io.Serializable; 4 import java.util.HashSet; 5 import java.util.Set; 6 7 public class Category implements Serializable{ 8 // category_id int primary key auto_increment, 9 // category_name varchar(50) not null 10 private Integer categoryId; 11 private String categoryName; 12 private Set<Book> books = new HashSet<Book>(); 13 public Integer getCategoryId() { 14 return categoryId; 15 } 16 public void setCategoryId(Integer categoryId) { 17 this.categoryId = categoryId; 18 } 19 public String getCategoryName() { 20 return categoryName; 21 } 22 public void setCategoryName(String categoryName) { 23 this.categoryName = categoryName; 24 } 25 public Set<Book> getBooks() { 26 return books; 27 } 28 public void setBooks(Set<Book> books) { 29 this.books = books; 30 } 31 @Override 32 public String toString() { 33 return "Category [categoryId=" + categoryId + ", categoryName=" + categoryName + "]"; 34 } 35 36 }
映射文件book.hbm.xml
set标签
table:对应的是中间表,没有实体类的,意味着靠两张主表对应的映射文件联合管理数据
name:当前映射文件对应的实体类对应的属性
cascade:级联新增修改,说白了就是当前实体类对应的表删除能否影响到关联表的数据
inberse:中间表的数据维护的权利交给对方
key标签
column:当前表t_hibernate_book_category的主键book_id在中间表的列段bid
many-to-many:
column:代表中间表对应的除去当前表t_hibernate_book的非主键的中间列段cid
class:cid对应的类
1 <?xml version="1.0" encoding="UTF-8"?> 2 <!DOCTYPE hibernate-mapping PUBLIC 3 "-//Hibernate/Hibernate Mapping DTD 3.0//EN" 4 "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> 5 <hibernate-mapping> 6 <class name="com.MavenHibernate.four.entity.Book" table="t_hibernate_book"> 7 <cache usage="read-only" region="com.zking.five.entity.Book"/> 8 <id name="bookId" type="java.lang.Integer" column="book_id"> 9 <generator class="increment" /> 10 </id> 11 <property name="bookName" type="java.lang.String" 12 column="book_name"> 13 </property> 14 <property name="price" type="java.lang.Float" 15 column="price"> 16 </property> 17 <!-- 18 set标签 19 table:对应的是中间表,没有实体类的,意味着靠两张主表对应的映射文件联合管理数据 20 name:当前映射文件对应的实体类对应的属性 21 cascade:级联新增修改,说白了就是当前实体类对应的表删除能否影响到关联表的数据 22 inberse:中间表的数据维护的权利交给对方 23 key标签 24 column:当前表t_hibernate_book_category的主键book_id在中间表的列段bid 25 many-to-many: 26 column:代表中间表对应的除去当前表t_hibernate_book的非主键的中间列段cid 27 class:cid对应的类 28 --> 29 <set table="t_hibernate_book_category" name="categories" cascade="save-update" inverse="true"> 30 <!-- one --> 31 <key column="bid"></key> 32 <!-- many --> 33 <many-to-many column="cid" class="com.MavenHibernate.four.entity.Category"></many-to-many> 34 </set> 35 </class> 36 </hibernate-mapping>
映射文件book.hbm.xml对应的实体类book
1 package com.MavenHibernate.four.entity; 2 3 import java.io.Serializable; 4 import java.util.HashSet; 5 import java.util.Set; 6 7 public class Book implements Serializable{ 8 // book_id int primary key auto_increment, 9 // book_name varchar(50) not null, 10 // price float not null 11 private Integer bookId; 12 private String bookName; 13 private Float price; 14 15 private Set<Category> categories = new HashSet<Category>(); 16 private Integer initCategories = 0; 17 18 public Integer getInitCategories() { 19 return initCategories; 20 } 21 22 public void setInitCategories(Integer initCategories) { 23 this.initCategories = initCategories; 24 } 25 26 public Integer getBookId() { 27 return bookId; 28 } 29 30 public void setBookId(Integer bookId) { 31 this.bookId = bookId; 32 } 33 34 public String getBookName() { 35 return bookName; 36 } 37 38 public void setBookName(String bookName) { 39 this.bookName = bookName; 40 } 41 42 public Float getPrice() { 43 return price; 44 } 45 46 public void setPrice(Float price) { 47 this.price = price; 48 } 49 50 public Set<Category> getCategories() { 51 return categories; 52 } 53 54 public void setCategories(Set<Category> categories) { 55 this.categories = categories; 56 } 57 58 @Override 59 public String toString() { 60 return "Book [bookId=" + bookId + ", bookName=" + bookName + ", price=" + price + "]"; 61 } 62 63 public Book(Integer bookId, String bookName) { 64 super(); 65 this.bookId = bookId; 66 this.bookName = bookName; 67 } 68 69 public Book() { 70 super(); 71 } 72 73 74 }
hibernate.cfg.xml中配置映射文件
BookDao
1 package com.MavenHibernate.four.dao; 2 3 import java.util.HashMap; 4 import java.util.List; 5 import java.util.Map; 6 7 import org.hibernate.Hibernate; 8 import org.hibernate.Session; 9 import org.hibernate.Transaction; 10 import org.hibernate.query.Query; 11 12 import com.MavenHibernate.two.util.SessionFactoryUtils; 13 import com.MavenHibernate.four.entity.Book; 14 import com.MavenHbernate.four.entity.Category; 15 import com.mysql.jdbc.StringUtils; 16 17 public class BookDao{ 18 public Integer addBook(Book book) { 19 Session session = SessionFactoryUtils.openSession(); 20 Transaction transaction = session.beginTransaction(); 21 Integer bid = (Integer) session.save(book); 22 transaction.commit(); 23 session.close(); 24 return bid; 25 } 26 27 public Integer addCategory(Category category) { 28 Session session = SessionFactoryUtils.openSession(); 29 Transaction transaction = session.beginTransaction(); 30 Integer cid = (Integer) session.save(category); 31 transaction.commit(); 32 session.close(); 33 return cid; 34 } 35 36 public Category getCategory(Category category) { 37 Session session = SessionFactoryUtils.openSession(); 38 Transaction transaction = session.beginTransaction(); 39 Category c = session.get(Category.class, category.getCategoryId()); 40 transaction.commit(); 41 session.close(); 42 return c; 43 } 44 45 public Book getBook(Book book) { 46 Session session = SessionFactoryUtils.openSession(); 47 Transaction transaction = session.beginTransaction(); 48 Book b = session.get(Book.class, book.getBookId()); 49 if (b != null && new Integer(1).equals(book.getInitCategories())) { 50 Hibernate.initialize(b.getCategories()); 51 } 52 transaction.commit(); 53 session.close(); 54 return b; 55 } 56 57 public void delBook(Book book) { 58 Session session = SessionFactoryUtils.openSession(); 59 Transaction transaction = session.beginTransaction(); 60 session.delete(book); 61 transaction.commit(); 62 session.close(); 63 } 64 65 public void delCategory(Category category) { 66 Session session = SessionFactoryUtils.openSession(); 67 Transaction transaction = session.beginTransaction(); 68 Category c = session.get(Category.class, category.getCategoryId()); 69 if(c!=null) { 70 for (Book b : c.getBooks()) { 71 // 通过在被控方通过主控方来解除关联关系,最后被控方再做删除 72 b.getCategories().remove(c); 73 } 74 } 75 session.delete(c); 76 transaction.commit(); 77 session.close(); 78 } 79 80 81 }
junit测试BookDao
BookDaoTest
1 package com.MavenHibernate.four.dao; 2 3 import org.junit.Test; 4 5 import com.MavenHibernate.four.entity.Book; 6 import com.MavenHbernate.four.entity.Category; 7 8 public class BookDaoTest { 9 private BookDao bookDao = new BookDao(); 10 11 @Test 12 public void testGetBook() { 13 Book book = new Book(); 14 book.setBookId(8); 15 book.setInitCategories(1); 16 Book b = this.bookDao.getBook(book ); 17 System.out.println(b.getBookName()); 18 System.out.println(b.getCategories()); 19 } 20 21 /** 22 * book.hbm.xml inverse=fasle 23 * category.hbm.xml inverse=true 24 * 数据添加正常 25 * 书籍表、桥接表各新增一条数据 26 */ 27 @Test 28 public void test1() { 29 Book book = new Book(); 30 book.setBookName("jt5555555"); 31 book.setPrice(10f); 32 Category category = new Category(); 33 category.setCategoryId(5); 34 // 直接将category对象加入到新建的book中是错误的,因为此时的category是临时态的,hibernate是不会管理的 35 // book.getCategories().add(category); 36 Category c = this.bookDao.getCategory(category); 37 38 // c.getBooks().add(book); 39 book.getCategories().add(c); 40 this.bookDao.addBook(book); 41 } 42 43 /** 44 * book.hbm.xml inverse=false 45 * category.hbm.xml inverse=true 46 * 只增加书籍表数据 47 * 桥接表不加数据 48 * 原因:双方都没有去维护关系 49 */ 50 @Test 51 public void test2() { 52 Book book = new Book(); 53 book.setBookName("T226"); 54 book.setPrice(10); 55 Category category = new Category(); 56 category.setCategoryId(5); 57 Category c = this.bookDao.getCategory(category); 58 59 book.getCategories().add(c); 60 this.bookDao.addBook(book); 61 // c.getBooks().add(book); 62 } 63 64 65 }