• hibernate关联关系(多对多)


     1. hibernate的多对多

       hibernate可以直接映射多对多关联关系(看作两个一对多)

     2 多对多关系注意事项

       2.1 一定要定义一个主控方
      2.2 多对多删除
        2.2.1 主控方直接删除
        2.2.2 被控方先通过主控方解除多对多关系,再删除被控方
        2.2.3 禁用级联删除
      2.3 关联关系编辑,不需要直接操作桥接表,hibernate的主控方会自动维护
     

     3 hibernate自关联案列

     3.1 表信息

     t_hibernate_sys_tree_node 

    3.2 实体类 TreeNode

     1 package com.yuan.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 + ", parent=" + parent + ", initChildren=" + initChildren
    84                 + "]";
    85     }
    86 
    87     
    88 
    89     
    90     
    91 
    92 }

     3.3 实体映射文件 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.yuan.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.yuan.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.yuan.four.entity.TreeNode"/>
    28         </set>
    29     </class>
    30 </hibernate-mapping>

    3.4 将实体映射文件配置到 hibernate.cfg.xml 核心配置文件中

        一对多自关联关系

     1 <?xml version="1.0" encoding="UTF-8"?>
     2 <!DOCTYPE hibernate-configuration PUBLIC
     3     "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
     4     "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
     5     <hibernate-configuration>
     6       <session-factory>
     7         <!-- 1. 数据库相关 -->
     8         <property name="connection.username">root</property>
     9         <property name="connection.password" >123</property>
    10         <property name="connection.url">jdbc:mysql://localhost:3306/xm_sc?useUnicode=true&amp;characterEncoding=UTF-8
    11         </property>
    12         <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
    13         <property name="dialect">org.hibernate.dialect.MySQLDialect</property>
    14 
    15         <!-- 配置本地事务(No CurrentSessionContext configured!) -->
    16         <property name="hibernate.current_session_context_class">thread</property>
    17 
    18         <!-- 2. 调试相关 -->
    19         <property name="show_sql">true</property>
    20         <property name="format_sql">true</property>
    21 
    22         <!-- 3. 添加实体映射文件 -->
    23         <mapping resource="com/yuan/one/entity/User.hbm.xml" />
    24         <!-- 主键生成策略 -->
    25         <mapping resource="com/yuan/two/Student.hbm.xml" />
    26         <mapping resource="com/yuan/two/Worker.hbm.xml"/>
    27         <!-- 一对多关联关系 -->
    28         <mapping resource="com/yuan/three/entity/Order.hbm.xml" />
    29         <mapping resource="com/yuan/three/entity/OrderItem.hbm.xml"/>
    30         <!-- 一对多自关联关系 -->
    31         <mapping resource="com/yuan/four/entity/TreeNode.hbm.xml"/>
    32         
    35 </session-factory> 36 </hibernate-configuration>

    3.5  dao层  TreeNodeDao

     1 package com.yuan.four.dao;
     2 
     3 import org.hibernate.Hibernate;
     4 import org.hibernate.Session;
     5 import org.hibernate.Transaction;
     6 
     7 import com.yuan.four.entity.TreeNode;
     8 import com.yuan.two.util.SessionFactoryUtils;
     9 
    10 
    11 public class TreeNodeDao {
    12     public TreeNode load(TreeNode treeNode) {
    13         Session session = SessionFactoryUtils.openSession();
    14         Transaction transaction = session.beginTransaction();
    15         TreeNode t = session.load(TreeNode.class, treeNode.getNodeId());
    16         if(t != null && new Integer(1).equals(treeNode.getInitChildren())) {
    17             Hibernate.initialize(t.getChildren());
    18             Hibernate.initialize(t.getParent());
    19         }
    20         transaction.commit();
    21         session.close();
    22         return t;
    23     }
    24 }

    3.6  使用junit测试dao方法  TreeNodeDaoTest

     1 package com.yuan.four.dao;
     2 
     3 import org.junit.Test;
     4 
     5 import com.yuan.four.entity.TreeNode;
     6 
     7 public class TreeNodeDaoTest {
     8 
     9     private TreeNodeDao treeNodeDao = new TreeNodeDao();
    10 
    11 //    @Before
    12 //    public void setUp() throws Exception {
    13 //    }
    14 //
    15 //    @After
    16 //    public void tearDown() throws Exception {
    17 //    }
    18 
    19     @Test
    20     public void testLoad() {
    21         TreeNode treeNode = new TreeNode();
    22         treeNode.setNodeId(6);
    23         treeNode.setInitChildren(1);
    24         
    25         TreeNode t = this.treeNodeDao.load(treeNode);
    26         System.out.println(t);
    27         System.out.println(t.getParent());
    28         System.out.println(t.getChildren());
    29     }
    30 
    31 
    32 }

     3.7 测试得到结果

    TreeNode [nodeId=6, nodeName=权限管理, treeNodeType=1, position=6, url=null, parent=TreeNode [nodeId=1, nodeName=系统管理, treeNodeType=1, position=1, url=null, parent=null, initChildren=0], initChildren=0]
    TreeNode [nodeId=1, nodeName=系统管理, treeNodeType=1, position=1, url=null, parent=null, initChildren=0]
    [TreeNode [nodeId=10, nodeName=用户分配角色, treeNodeType=2, position=10, url=null, parent=TreeNode [nodeId=6, nodeName=权限管理, treeNodeType=1, position=6, url=null, parent=TreeNode [nodeId=1, nodeName=系统管理, treeNodeType=1, position=1, url=null, parent=null, initChildren=0], initChildren=0], initChildren=0], TreeNode [nodeId=11, nodeName=角色授予用户, treeNodeType=2, position=11, url=null, parent=TreeNode [nodeId=6, nodeName=权限管理, treeNodeType=1, position=6, url=null, parent=TreeNode [nodeId=1, nodeName=系统管理, treeNodeType=1, position=1, url=null, parent=null, initChildren=0], initChildren=0], initChildren=0]]

    4. 多对多关联关系案列

    4.1 表信息

     t_hibernate_book 

    t_hibernate_book_category  中间表

    t_hibernate_category

    4.2 创建实体类 

     Book.java

     1 package com.yuan.four.entity;
     2 
     3 import java.io.Serializable;
     4 import java.util.HashSet;
     5 import java.util.Set;
     6 
     7 /**
     8  * 一对多,一本书对应多种书本类型
     9  * @author ly
    10  *
    11  */
    12 public class Book implements Serializable{
    13 //    book_id int primary key auto_increment,
    14 //       book_name varchar(50) not null,
    15 //       price float not null
    16     private Integer bookId;
    17     private String bookName;
    18     private Float price;
    19     
    20     private Set<Category> categories = new HashSet<Category>();
    21     private Integer initCategories = 0;
    22 
    23     public Integer getInitCategories() {
    24         return initCategories;
    25     }
    26 
    27     public void setInitCategories(Integer initCategories) {
    28         this.initCategories = initCategories;
    29     }
    30 
    31     public Integer getBookId() {
    32         return bookId;
    33     }
    34 
    35     public void setBookId(Integer bookId) {
    36         this.bookId = bookId;
    37     }
    38 
    39     public String getBookName() {
    40         return bookName;
    41     }
    42 
    43     public void setBookName(String bookName) {
    44         this.bookName = bookName;
    45     }
    46 
    47     public Float getPrice() {
    48         return price;
    49     }
    50 
    51     public void setPrice(Float price) {
    52         this.price = price;
    53     }
    54 
    55     public Set<Category> getCategories() {
    56         return categories;
    57     }
    58 
    59     public void setCategories(Set<Category> categories) {
    60         this.categories = categories;
    61     }
    62 
    63     @Override
    64     public String toString() {
    65         return "Book [bookId=" + bookId + ", bookName=" + bookName + ", price=" + price + "]";
    66     }
    67 
    68     public Book(Integer bookId, String bookName) {
    69         super();
    70         this.bookId = bookId;
    71         this.bookName = bookName;
    72     }
    73 
    74     public Book() {
    75         super();
    76     }
    77     
    78     
    79 }

     category.java

     1 package com.yuan.four.entity;
     2 
     3 import java.io.Serializable;
     4 import java.util.HashSet;
     5 import java.util.Set;
     6 
     7 /**
     8  * 一对多,一种书本类型对应多本书
     9  * @author ly
    10 * 11 */ 12 public class Category implements Serializable{ 13 // category_id int primary key auto_increment, 14 // category_name varchar(50) not null 15 private Integer categoryId; 16 private String categoryName; 17 private Set<Book> books = new HashSet<Book>(); 18 public Integer getCategoryId() { 19 return categoryId; 20 } 21 public void setCategoryId(Integer categoryId) { 22 this.categoryId = categoryId; 23 } 24 public String getCategoryName() { 25 return categoryName; 26 } 27 public void setCategoryName(String categoryName) { 28 this.categoryName = categoryName; 29 } 30 public Set<Book> getBooks() { 31 return books; 32 } 33 public void setBooks(Set<Book> books) { 34 this.books = books; 35 } 36 @Override 37 public String toString() { 38 return "Category [categoryId=" + categoryId + ", categoryName=" + categoryName + "]"; 39 } 40 41 }

    4.3 实体类对应的实体映射文件

      book.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.yuan.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         <!-- 
    19            set标签:
    20               table:对应的是中间表,没有实体类的,意味着两张主表对应的映射文件联合管理数据
    21               name:当前映射文件对应的实体类对应的属性
    22               cascade:级联新增修改,说白了就是当前实体类对应的表删除能否影响到关联表的数据
    23               inverse:中间表的数据维护的权力交给对方
    24            key标签:
    25               column:当前表t_hibernate_book的主键book_id在中间表的列段bid
    26            many-to-many:
    27            column:代表中间表对应的除去当前表t_hibernate_book的非主键的中间表列段cid
    28            class:cid对应的类
    29               
    30            
    31          -->
    32         <set table="t_hibernate_book_category" name="categories" cascade="save-update" inverse="false">
    33             <!-- one -->
    34             <key column="bid"></key>
    35             <!-- many -->
    36             <many-to-many column="cid" class="com.yuan.four.entity.Category"></many-to-many>
    37         </set>
    38     </class>
    39 </hibernate-mapping>

     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.yuan.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.yuan.four.entity.Book"></many-to-many>
    17         </set>
    18     </class>
    19 </hibernate-mapping>

    4.4 将实体映射文件配置到hibernate.cfg.xml 中

     1 <?xml version="1.0" encoding="UTF-8"?>
     2 <!DOCTYPE hibernate-configuration PUBLIC
     3     "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
     4     "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
     5     <hibernate-configuration>
     6       <session-factory>
     7         <!-- 1. 数据库相关 -->
     8         <property name="connection.username">root</property>
     9         <property name="connection.password" >123</property>
    10         <property name="connection.url">jdbc:mysql://localhost:3306/xm_sc?useUnicode=true&amp;characterEncoding=UTF-8
    11         </property>
    12         <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
    13         <property name="dialect">org.hibernate.dialect.MySQLDialect</property>
    14 
    15         <!-- 配置本地事务(No CurrentSessionContext configured!) -->
    16         <property name="hibernate.current_session_context_class">thread</property>
    17 
    18         <!-- 2. 调试相关 -->
    19         <property name="show_sql">true</property>
    20         <property name="format_sql">true</property>
    21 
    22         <!-- 3. 添加实体映射文件 -->
    23         <mapping resource="com/yuan/one/entity/User.hbm.xml" />
    24         <!-- 主键生成策略 -->
    25         <mapping resource="com/yuan/two/Student.hbm.xml" />
    26         <mapping resource="com/yuan/two/Worker.hbm.xml"/>
    27         <!-- 一对多关联关系 -->
    28         <mapping resource="com/yuan/three/entity/Order.hbm.xml" />
    29         <mapping resource="com/yuan/three/entity/OrderItem.hbm.xml"/>
    30         <!-- 一对多自关联关系 -->
    31         <mapping resource="com/yuan/four/entity/TreeNode.hbm.xml"/>
    32         <!-- 多对多关联关系 -->
    33         <mapping resource="com/yuan/four/entity/book.hbm.xml"/>
    34         <mapping resource="com/yuan/four/entity/category.hbm.xml"/>
    35       </session-factory>
    36     </hibernate-configuration>

     4.5 编写dao层

      BookDao

     1 package com.yuan.four.dao;
     2 
     3 
     4 import org.hibernate.Hibernate;
     5 import org.hibernate.Session;
     6 import org.hibernate.Transaction;
     7 
     8 import com.yuan.four.entity.Book;
     9 import com.yuan.four.entity.Category;
    10 import com.yuan.two.util.SessionFactoryUtils;
    11 
    12 
    13 public class BookDao {
    14     public Integer addBook(Book book) {
    15         Session session = SessionFactoryUtils.openSession();
    16         Transaction transaction = session.beginTransaction();
    17         Integer bid = (Integer) session.save(book);
    18         transaction.commit();
    19         session.close();
    20         return bid;
    21     }
    22     
    23     public Integer addCategory(Category category) {
    24         Session session = SessionFactoryUtils.openSession();
    25         Transaction transaction = session.beginTransaction();
    26         Integer cid = (Integer) session.save(category);
    27         transaction.commit();
    28         session.close();
    29         return cid;
    30     }
    31     
    32     public Category getCategory(Category category) {
    33         Session session = SessionFactoryUtils.openSession();
    34         Transaction transaction = session.beginTransaction();
    35         Category c = session.get(Category.class, category.getCategoryId());
    36         transaction.commit();
    37         session.close();
    38         return c;
    39     }
    40     
    41     public Book getBook(Book book) {
    42         Session session = SessionFactoryUtils.openSession();
    43         Transaction transaction = session.beginTransaction();
    44         Book b = session.get(Book.class, book.getBookId());
    45         if (b != null && new Integer(1).equals(book.getInitCategories())) {
    46             Hibernate.initialize(b.getCategories());
    47         }
    48         transaction.commit();
    49         session.close();
    50         return b;
    51     }
    52     
    53     public void delBook(Book book) {
    54         Session session = SessionFactoryUtils.openSession();
    55         Transaction transaction = session.beginTransaction();
    56         session.delete(book);
    57         transaction.commit();
    58         session.close();
    59     }
    60     
    61     public void delCategory(Category category) {
    62         Session session = SessionFactoryUtils.openSession();
    63         Transaction transaction = session.beginTransaction();
    64         Category c = session.get(Category.class, category.getCategoryId());
    65         if(c!=null) {
    66             for (Book b : c.getBooks()) {
    67 //                通过在被控方通过主控方来解除关联关系,最后被控方再做删除
    68                 b.getCategories().remove(c);
    69             }
    70         }
    71         session.delete(c);
    72         transaction.commit();
    73         session.close();
    74     }
    75     
    76     
    77     
    78 }

    4.6 BookDao 的junit测试 BookDaoTest

     1 package com.yuan.four.dao;
     2 
     3 import org.junit.Test;
     4 
     5 import com.yuan.four.entity.Book;
     6 import com.yuan.four.entity.Category;
     7 
     8 
     9 public class BookDaoTest {
    10     private BookDao bookDao = new BookDao();
    11     //获取单本书籍部分信息
    12     @Test
    13     public void testGetBook() {
    14         Book book = new Book();
    15         book.setBookId(8);
    16         book.setInitCategories(1);
    17         Book b = this.bookDao.getBook(book );
    18         System.out.println(b.getBookName());
    19         System.out.println(b.getCategories());
    20     }
    21     
    22     /**
    23      * book.hbm.xml    inverse=false
    24      * category.hbm.xml inverse=true
    25      * 数据添加正常
    26      * 书籍表、桥接表各新增一条数据
    27      */
    28     @Test
    29     public void test1() {
    30         Book book = new Book();
    31         book.setBookName("yuan");
    32         book.setPrice(10f);
    33         Category category = new Category();
    34         category.setCategoryId(5);
    35 //        直接将category对象加入到新建的book中是错误的,因为此时的category是临时态的,hibernate是不会管理的
    36 //        book.getCategories().add(category);
    37         Category c = this.bookDao.getCategory(category);
    38         
    39 //        c.getBooks().add(book);
    40         book.getCategories().add(c);
    41         this.bookDao.addBook(book);
    42     }
    43 
    44     /**
    45      * book.hbm.xml    inverse=true
    46      * category.hbm.xml inverse=true
    47      * 只增加书籍表数据
    48      * 桥接表不加数据
    49      * 原因:双方都没有去维护关系
    50      */
    51     @Test
    52     public void test2() {
    53         Book book = new Book();
    54         book.setBookName("yuan2");
    55         book.setPrice(10f);
    56         Category category = new Category();
    57         category.setCategoryId(5);
    58         Category c = this.bookDao.getCategory(category);
    59         
    60         book.getCategories().add(c);
    61         this.bookDao.addBook(book);
    62 //        c.getBooks().add(book);
    63     }
    64     
    65     
    66 }

    4.7 测试结果

      注:测试时请根据测试方法上的注解进行修改

    4.7.1 testGetBook() 方法测试

    4.7.2 test1()测试

      t_hibernate_book表新增一条数据

      同时 t_hibernate_book_category 表新增一条数据

    4.7.3 test2()测试 

     t_hibernate_book新增数据

    但t_hibernate_book_category不新增数据

      

           完 !!!

  • 相关阅读:
    张旭结对编程作业
    团队第一次作业(软工C#造梦厂)
    张旭第二次作业
    跨域问题
    .Net Core3.1使用AspectCore
    .Net中HttpClient之SendAsync方法
    两个具有相同属性的类赋值
    工具类--HttpUtils
    工具类--CacheHelper
    工具类--JsonHelper
  • 原文地址:https://www.cnblogs.com/ly-0919/p/11319827.html
Copyright © 2020-2023  润新知