zoukankan      html  css  js  c++  java
  • Hibernate 一对多自关联 多对多

    一对多自关联(说白了就是自己关联自己)比如:

    商城里面的分类,一级分类:电器,家具等等。

               电器下面分二级分类:厨房电器,生活电器等等。

               二级分类厨房电器下的三级分类:电压力锅,电磁炉等等。。   

    数据库:

    实体类:(TreeNode)

    package com.chenjiahao.four.entity;
    
    import java.util.HashSet;
    import java.util.Set;
    
    public class TreeNode {
    private Integer nodeId;
    private String nodeName;
    private Integer treeNodeType;
    private Integer position;
    private String url;
    private TreeNode parent;
    private Set<TreeNode> children = new HashSet<TreeNode>();
    private Integer initChildren = 0;
    //0懒加载 1、强制加载(子节点)2、强制加载用户 3、强制加载两个
    
    public Integer getNodeId() {
    return nodeId;
    }
    
    public void setNodeId(Integer nodeId) {
    this.nodeId = nodeId;
    }
    
    public String getNodeName() {
    return nodeName;
    }
    
    public void setNodeName(String nodeName) {
    this.nodeName = nodeName;
    }
    
    public Integer getTreeNodeType() {
    return treeNodeType;
    }
    
    public void setTreeNodeType(Integer treeNodeType) {
    this.treeNodeType = treeNodeType;
    }
    
    public Integer getPosition() {
    return position;
    }
    
    public void setPosition(Integer position) {
    this.position = position;
    }
    
    public String getUrl() {
    return url;
    }
    
    public void setUrl(String url) {
    this.url = url;
    }
    
    public TreeNode getParent() {
    return parent;
    }
    
    public void setParent(TreeNode parent) {
    this.parent = parent;
    }
    
    public Set<TreeNode> getChildren() {
    return children;
    }
    
    public void setChildren(Set<TreeNode> children) {
    this.children = children;
    }
    
    public Integer getInitChildren() {
    return initChildren;
    }
    
    public void setInitChildren(Integer initChildren) {
    this.initChildren = initChildren;
    }
    
    //	@Override
    //	public String toString() {
    //	return "TreeNode [nodeId=" + nodeId + ", nodeName=" + nodeName + ", treeNodeType=" + treeNodeType
    //	+ ", position=" + position + ", url=" + url + ", children=" + children + "]";
    //	}
    
    @Override
    public String toString() {
    return "TreeNode [nodeId=" + nodeId + ", nodeName=" + nodeName + ", treeNodeType=" + treeNodeType
    + ", position=" + position + ", url=" + url + "]";
    }
    }
    

      

      TreeNode.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.chenjiahao.four.entity.TreeNode" table="t_hibernate_sys_tree_node">
    		<id name="nodeId" type="java.lang.Integer" column="tree_node_id">
    			<generator class="increment" />
    		</id>
    		<property name="nodeName" type="java.lang.String"
    			column="tree_node_name">
    		</property>
    		<property name="treeNodeType" type="java.lang.Integer"
    			column="tree_node_type">
    		</property>
    		<property name="position" type="java.lang.Integer"
    			column="position">
    		</property>
    		<property name="url" type="java.lang.String"
    			column="url">
    		</property>
    		
    		<many-to-one name="parent" class="com.chenjiahao.four.entity.TreeNode" column="parent_node_id"/>
    		
    		<set name="children" cascade="save-update" inverse="true">
    			<key column="parent_node_id"></key>
    			<one-to-many class="com.chenjiahao.four.entity.TreeNode"/>
    		</set>
    	</class>
    </hibernate-mapping>
    

      


    在主配置文件/hibernate.cfg.xml中加:

     <!-- 一对多自关联 -->
            <mapping resource="com/chenjiahao/four/entity/TreeNode.hbm.xml"/>
    

      TreeNodeDao层

    package com.chenjiahao.four.dao;
    
    import org.hibernate.Hibernate;
    import org.hibernate.Session;
    import org.hibernate.Transaction;
    
    import com.chenjiahao.four.entity.TreeNode;
    import com.chenjiahao.two.util.SessionFactoryUtils;
    
    
    
    public class TreeNodeDao {
    	public TreeNode load(TreeNode treeNode) {
    		Session session = SessionFactoryUtils.openSession();
    		Transaction transaction = session.beginTransaction();
    		TreeNode t = session.load(TreeNode.class, treeNode.getNodeId());
    	
    		if(t != null && new Integer(1).equals(treeNode.getInitChildren())) {
    			Hibernate.initialize(t.getChildren());
    			Hibernate.initialize(t.getParent());
    		}
    		transaction.commit();
    		session.close();
    		return t;
    	}
    }
    

      

    TreeNodeDaoTest测试:

    package com.chenjiahao.four.dao;
    
    import org.junit.Test;
    
    import com.chenjiahao.four.entity.TreeNode;
    
    
    
    
    public class TreeNodeDaoTest {
    	private TreeNodeDao treeNodeDao = new TreeNodeDao();
    
    //	@Before
    //	public void setUp() throws Exception {
    //	}
    //
    //	@After
    //	public void tearDown() throws Exception {
    //	}
    
    	@Test
    	public void testLoad() {
    		TreeNode treeNode = new TreeNode();
    		treeNode.setNodeId(6);
    		treeNode.setInitChildren(1);
    		
    		TreeNode t = this.treeNodeDao.load(treeNode);
    		//拿到当前节点
    		System.out.println(t);
    		//拿到当前节点的父节点
    		System.out.println(t.getParent());
    		//拿到当前节点的 子节点
    		System.out.println(t.getChildren());
    	}
    
    }
    

      多对多

    数据库的多对多:

          数据库中不能直接映射多对多
          处理:创建一个桥接表(中间表),将一个多对多关系转换成两个一对多

          注:数据库多表联接查询,永远就是二个表的联接查询

    hibernate的多对多:

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

    多对多关系注意事项:一定要定义一个主控方     

    书本表:t_hibernate_book;
    书本类别表:t_hibernate_category;
    中间表: t_hibernate_book_category;

    t_hibernate_book;

    t_hibernate_category;

    t_hibernate_book_category

    实体类和xml配置:

    Book:

    public class Book implements Serializable{
    //	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;
    }
    

      Category:

    public class Category implements Serializable{
    //	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<Book>();
    }
    

     incerse在下面book.hbm.xml和Category.hbm.xml里面都体现了,incerse主要是维护中间表。

      book.hbm.xml inverse=false
      category.hbm.xml inverse=false
      数据添加正常
      书籍表、书籍类别关联表各新增一条数据

     

      book.hbm.xml inverse=true
      category.hbm.xml inverse=true
      只增加书籍表数据
      书籍类别关联表不加数据
      原因:双方都没有去维护关系



    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.chenjiahao.four.entity.Category" table="t_hibernate_category">
    		<id name="categoryId" type="java.lang.Integer" column="category_id">
    			<generator class="increment" />
    		</id>
    		<property name="categoryName" type="java.lang.String"
    			column="category_name">
    		</property>
    		
    		<set table="t_hibernate_book_category" name="books" cascade="save-update" inverse="false">
    			<key column="cid"></key>
    			<many-to-many column="bid" class="com.chenjiahao.four.entity.Book"></many-to-many>
    		</set>
    	</class>
    </hibernate-mapping>
    

      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.chenjiahao.four.entity.Book" table="t_hibernate_book">
    		<cache usage="read-only" region="com.zking.five.entity.Book"/>
    		<id name="bookId" type="java.lang.Integer" column="book_id">
    			<generator class="increment" />
    		</id>
    		<property name="bookName" type="java.lang.String"
    			column="book_name">
    		</property>
    		<property name="price" type="java.lang.Float"
    			column="price">
    		</property>
    		<!-- 
    		     table:代表的是中间表
    		     name:书籍的关联属性
    		     inverse:中间表交于对方维护
    		     key:当前类对应的表列段在中间表(t_hibernate_book_category)中的外键bid
    		     many-to-many:
    		             column:对应的是上面key查出来中间表(t_hibernate_book_category)另一个字段cid,当作关联表的主键(category_id)进行查询
    		             class:上述查出来的主键对应的实体类
    		     流程:
    		     以查询book_id=1西游记这本书为例
    		     1、通过建模反射自动生成sql,可以拿到book_id这条记录的基本信息{book_id=1,book_name=西游记,book_price=50}
    		     2、book_id=1->bid=1去查询中间表t_hibernate_book_category,拿到了cid=1,2
    		     3、cid=1,2->t_hibernate_category的category_id=1,2
    		     4、拿到当前book实列对应的categroy的集合
    		     5、最终{book_id=1,book_name=西游记,book_price=50}->
    		     {book_id=1,book_name=西游记,book_price=50,category=[categoryId=2, categoryName=神话], Category [categoryId=1, categoryName=古典]]}
    		 -->
    		<set table="t_hibernate_book_category" name="categories" cascade="save-update" inverse="false">
    			<!-- one -->
    			<key column="bid"></key>
    			<!-- many -->
    			<many-to-many column="cid" class="com.chenjiahao.four.entity.Category"></many-to-many>
    		</set>
    	</class>
    </hibernate-mapping>
    

      在主配置文件/hibernate.cfg.xml中加:

    <!-- 多对多的自关联 -->
            <mapping resource="com/chenjiahao/four/entity/Book.hbm.xml"/>
            <mapping resource="com/chenjiahao/four/entity/Category.hbm.xml"/
    

    dao层:

    package com.chenjiahao.four.dao;
    
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    
    import org.hibernate.Hibernate;
    import org.hibernate.Session;
    import org.hibernate.Transaction;
    import org.hibernate.query.Query;
    
    import com.chenjiahao.four.entity.Book;
    import com.chenjiahao.four.entity.Category;
    import com.chenjiahao.two.util.SessionFactoryUtils;
    
    
    import antlr.StringUtils;
    
    public class BookDao {
    	
    	public Integer addBook(Book book) {
    		Session session = SessionFactoryUtils.openSession();
    		Transaction transaction = session.beginTransaction();
    		Integer bid = (Integer) session.save(book);
    		transaction.commit();
    		session.close();
    		return bid;
    	}
    	
    	public Integer addCategory(Category category) {
    		Session session = SessionFactoryUtils.openSession();
    		Transaction transaction = session.beginTransaction();
    		Integer cid = (Integer) session.save(category);
    		transaction.commit();
    		session.close();
    		return cid;
    	}
    	
    	public Category getCategory(Category category) {
    		Session session = SessionFactoryUtils.openSession();
    		Transaction transaction = session.beginTransaction();
    		Category c = session.get(Category.class, category.getCategoryId());
    		transaction.commit();
    		session.close();
    		return c;
    	}
    	
    	public Book getBook(Book book) {
    		Session session = SessionFactoryUtils.openSession();
    		Transaction transaction = session.beginTransaction();
    		Book b = session.get(Book.class, book.getBookId());
    		if (b != null && new Integer(1).equals(book.getInitCategories())) {
    			Hibernate.initialize(b.getCategories());
    		}
    		transaction.commit();
    		session.close();
    		return b;
    	}
    	
    	public void delBook(Book book) {
    		Session session = SessionFactoryUtils.openSession();
    		Transaction transaction = session.beginTransaction();
    		session.delete(book);
    		transaction.commit();
    		session.close();
    	}
    	
    	public void delCategory(Category category) {
    		Session session = SessionFactoryUtils.openSession();
    		Transaction transaction = session.beginTransaction();
    		Category c = session.get(Category.class, category.getCategoryId());
    		if(c!=null) {
    			for (Book b : c.getBooks()) {
    //				通过在被控方通过主控方来解除关联关系,最后被控方再做删除
    				b.getCategories().remove(c);
    			}
    		}
    		session.delete(c);
    		transaction.commit();
    		session.close();
    	}
    	
    	
    
    }
    

      测试:

    package com.chenjiahao.four.dao;
    
    import org.junit.Test;
    
    import com.chenjiahao.four.entity.Book;
    import com.chenjiahao.four.entity.Category;
    
    public class BookDaoTest {
    	private BookDao bookDao = new BookDao();
    
    	@Test
    	public void testGetBook() {
    		Book book = new Book();
    		book.setBookId(1);
    		book.setInitCategories(1);
    		Book b = this.bookDao.getBook(book );
    		System.out.println(b.getBookName());
    		System.out.println(b.getCategories());
    	}
    	
    	/**
    	 * book.hbm.xml	inverse=false
    	 * category.hbm.xml inverse=true
    	 * 数据添加正常
    	 * 书籍表、桥接表各新增一条数据
    	 */
    	
    	@Test
    	public void test1() {
    		Book book = new Book();
    		book.setBookName("00咖啡店说课稿5");
    		book.setPrice(10f);
    		Category category = new Category();
    		category.setCategoryId(1);
    //		直接将category对象加入到新建的book中是错误的,因为此时的category是临时态的,hibernate是不会管理的
    //		book.getCategories().add(category);
    		//将数据库里面的类别数据查找出来
    		Category c = this.bookDao.getCategory(category);
    		
    //		c.getBooks().add(book);
    		book.getCategories().add(c);
    		this.bookDao.addBook(book);
    		
    	}
    
    
    	/**
    	 * book.hbm.xml	inverse=true
    	 * category.hbm.xml inverse=true
    	 * 只增加书籍表数据
    	 * 桥接表不加数据
    	 * 原因:双方都没有去维护关系
    	 */
    	@Test
    	public void test2() {
    		Book book = new Book();
    		book.setBookName("斗宗强者");
    		book.setPrice(10f);
    		Category category = new Category();
    		category.setCategoryId(5);
    		Category c = this.bookDao.getCategory(category);
    		
    		book.getCategories().add(c);
    		this.bookDao.addBook(book);
    //		c.getBooks().add(book);
    	}
    	
    	
    }
    

      

      

  • 相关阅读:
    9.16动手又动脑
    C#中集合的交集:Intersect问题
    LeetCode Easy: 27. Remove Element
    LeetCode Easy: 26.Remove Duplicates from Sorted Array
    LeetCode Easy: 21. Merge Two Sorted Lists
    LeetCode Easy: 20. Valid Parentheses
    LeetCode Easy: 14. Longest Common Prefix
    LeetCode Easy: 13. Roman to Integer
    LeetCode Easy: Palindrome Number
    DL: 初试 tensorflow
  • 原文地址:https://www.cnblogs.com/chenjiahao9527/p/11203293.html
Copyright © 2011-2022 走看看