hibernate 多对多关系(一)

什么是多对多关系呢?

关系数据库中两个表之间的一种关系, 该关系中第一个表中的一个行可以与第二个表中的一个或多个行相关。第二个表中的一个行也可以与第一个表中的一个或多个行相关。

比如在常见的订单管理数据库当中“产品”表和“订单”表之间的关系。单个订单中可以包含多个产品。另一方面,一个产品可能出现在多个订单中。

要表示多对多关系,就妖创建第三个表,称为 联接表,也称( 桥接表、中间表)。它多对多关系分Wie两个一对多关系。将连个主键都放在第三个表中,因此,第三个表记录关系的每个匹配项或实例。

不多说,我们实例来战:嘻嘻嘻

Example1:自关联查询 树形菜单表

TreeNode.jsp ,实现set/get方法

当前节点对父节点 多对一
父节点对子节点 一对多
*/

	private Integer treeNodeId;
	private String treeNodeName;
	private Integer treeNodeType;
	private Integer position;
	private String url;
	
//	private Set<TreeNode> children = new HashSet<TreeNode>();//一对多
	private List<TreeNode> children = new ArrayList<TreeNode>();//一对多,用List是为了可以排序
	private TreeNode parent;//外键 多对多
	private Integer IntiChildren = 0;
	
	public Integer getTreeNodeId() {
		return treeNodeId;
	}
	public void setTreeNodeId(Integer treeNodeId) {
		this.treeNodeId = treeNodeId;
	}

写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 table="t_hibernate_sys_tree_node" name="com.zking.five.entity.TreeNode">
		<id name="treeNodeId" type="java.lang.Integer" column="tree_node_id">
			<generator class="increment"></generator>
		</id>
		<property name="treeNodeName" 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>
		
		<!-- <set  name="children" cascade="save-update" inverse="true">
			<key column="parent_node_id"></key>
			<one-to-many class="com.zking.five.entity.TreeNode"/>
		</set> -->
		<!--bag 用于排序  order-by 指的是数据库中的表字段 -->
		<bag order-by="position" name="children" cascade="save-update" inverse="true">
			<key column="parent_node_id"></key>
			<one-to-many class="com.zking.five.entity.TreeNode"/>
		</bag>
		<many-to-one name="parent" class="com.zking.five.entity.TreeNode" column="parent_node_id"/>
	</class>
</hibernate-mapping>

写一个简单的dao

package com.zking.five.dao;
 
import org.hibernate.Hibernate;
import org.hibernate.Session;
import org.hibernate.Transaction;
 
import com.zking.five.entity.TreeNode;
import com.zking.two.util.SessionFactoryUtils;
 
public class TreeNodeDao {
	public TreeNode get(TreeNode treeNode) {
		Session session = SessionFactoryUtils.getSession();
		Transaction transaction = session.beginTransaction();
		TreeNode tn = session.get(TreeNode.class, treeNode.getTreeNodeId());
		if(tn !=null && new Integer(1).equals(treeNode.getIntiChildren())) {
			Hibernate.initialize(tn.getChildren());
		}
//		System.out.println(tn);
		transaction.commit();
		session.close();
		return tn;
	}
}

用Junit测试

package com.zking.five.dao;
 
import static org.junit.Assert.*;
 
import org.junit.Before;
import org.junit.Test;
 
import com.zking.five.entity.TreeNode;
 
public class TreeNodeDaoTest {
	private TreeNodeDao treeNodeDao =new TreeNodeDao();
	@Before
	public void setUp() throws Exception {
	}
 
	@Test
	public void testGet() {
		TreeNode treeNode = new TreeNode();
		treeNode.setTreeNodeId(1);
		treeNode.setIntiChildren(1);
		TreeNode tn = this.treeNodeDao.get(treeNode);
		System.out.println(tn.getTreeNodeId()+","+tn.getTreeNodeName());
		for(TreeNode tn2 : tn.getChildren()) {
			System.out.println(tn2.getTreeNodeId()+","+tn2.getTreeNodeName());
		}
			}
 
}

这样的原理是:

当加载一级节点时,ok
加载二级节点时,由于设置了强制加载,但同样可以加载所有的二级节点,ok
加载三级节点时,session关闭,并且默认采用的是懒加载

权限菜单加载有两种方式

  • 1.一次性将数据库中的数据全部加载往浏览器返回(适用于菜单较少)
  • 2、菜单表数据量较大,当出现浏览器卡顿的情况,第一种方式就不在使用。
  • 采用第二种:菜单逐级加载。

Example2: 多对多级联查询 书籍表、书籍类别表

书籍可以对应多个类别,而类别也可以对应多本书,所以是多对多的关系。

Book表的主键:book_id category类别表的主键:category_id 而他们在连接表分别的主键是bid和cid

在Book.hbm.xml配置文件中 通过自动关联联接表,以及关联查询出关联对象。

	<!-- 自动关联桥接表 -->
	<set table="t_hibernate_book_category" name="categorys" cascade="save-update" inverse="false">
		<!--one  bid 代表的是一对多的关系,也就是书籍对应的多个类别-->
		<key column="bid"></key>
		<!-- many  cid代表的是多对多的关系 去查类别表-->
		<many-to-many column="cid" class="com.zking.five.entity.Category"/>
	</set>
	
	
</class>

类别表的配置文件也是同一个道理

<?xml version="1.0" encoding="UTF-8"?>
	<set table="t_hibernate_book_category" name="books" cascade="save-update" inverse="true">
		<key column="cid"></key>
		<many-to-many column="bid" class="com.zking.five.entity.Book"/>
	</set>
</class>

总结:

在hibernate中,你只管查询当前表对象即可

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值