1. 程式人生 > >Hibernate 的一對多自關聯

Hibernate 的一對多自關聯

關於查詢許可權選單的載入一般有兩種方法
1,直接查詢出全部的選單載入到瀏覽器頁面
2,類似於Hibernate中的懶載入,第一次載入一級節點與二級節點,
當點選二級節點再去後臺查詢三級節點用於瀏覽器的展示

  1. 實體類
package com.more.entity;

import java.util.ArrayList;
import java.util.List;

public class TreeNode {

	private Integer TreeNodeId;  //許可權id
	private String  TreeNodeName; //許可權名
	private Integer TreeNodeType; 
	private Integer position;
	private Integer parentNodeId;  //它的父許可權Id
	private String  url;
	
	//一個兒子一個父親
	private TreeNode treeNode;
	//一個父親多個兒子
	private List<TreeNode> treeNodes=new ArrayList<>();
	
	//強制載入
	private Integer initTreeNode;

	public Integer getTreeNodeId() {
		return TreeNodeId;
	}

	public void setTreeNodeId(Integer treeNodeId) {
		TreeNodeId = treeNodeId;
	}

	public String getTreeNodeName() {
		return TreeNodeName;
	}

	public void setTreeNodeName(String treeNodeName) {
		TreeNodeName = treeNodeName;
	}

	public Integer getTreeNodeType() {
		return TreeNodeType;
	}

	public void setTreeNodeType(Integer treeNodeType) {
		TreeNodeType = treeNodeType;
	}

	public Integer getPosition() {
		return position;
	}

	public void setPosition(Integer position) {
		this.position = position;
	}

	public Integer getParentNodeId() {
		return parentNodeId;
	}

	public void setParentNodeId(Integer parentNodeId) {
		this.parentNodeId = parentNodeId;
	}

	public String getUrl() {
		return url;
	}

	public void setUrl(String url) {
		this.url = url;
	}

	public TreeNode getTreeNode() {
		return treeNode;
	}

	public void setTreeNode(TreeNode treeNode) {
		this.treeNode = treeNode;
	}

	public List<TreeNode> getTreeNodes() {
		return treeNodes;
	}

	public void setTreeNodes(List<TreeNode> treeNodes) {
		this.treeNodes = treeNodes;
	}

	public Integer getInitTreeNode() {
		return initTreeNode;
	}

	public void setInitTreeNode(Integer initTreeNode) {
		this.initTreeNode = initTreeNode;
	}

	@Override
	public String toString() {
		return "TreeNode [TreeNodeId=" + TreeNodeId + ", TreeNodeName=" + TreeNodeName + ", TreeNodeType="
				+ TreeNodeType + ", position=" + position + ", parentNodeId=" + parentNodeId + ", url=" + url
				+ ", treeNodes=" + treeNodes + "]";
	}

}

  1. 實體類的對映檔案
<?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>
	<!-- table: 資料庫表 name : 資料庫表對應的實體類的全限定名 -->
	<class name="com.more.entity.TreeNode" table="t_hibernate_sys_tree_node">
		<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 name="TreeNodeType" type="java.lang.Integer" column="tree_node_type"/>
		<property name="position" type="java.lang.Integer" column="position"/>
		<property name="parentNodeId" type="java.lang.Integer" column="parent_node_id"/>
		<property name="url" type="java.lang.String" column="url"/>

       <!-- 重複對映錯誤解決  insert="false" update="false" -->
        <many-to-one name="treeNode" class="com.more.entity.TreeNode" column="parent_node_id" insert="false" update="false"/>
        
        <bag order-by="position" name="treeNodes" cascade="save-update" inverse="true">
          <!-- 配置外來鍵關鍵欄位 -->
          <key column="parent_node_id"/>
              <!-- 配置外來鍵關聯的表  -->
          <one-to-many class="com.more.entity.TreeNode"/>
        </bag>
        

	</class>
</hibernate-mapping>
  1. 查詢方法
package com.more.dao;

import org.hibernate.Hibernate;
import org.hibernate.Session;

import com.more.entity.TreeNode;
import com.strurts.utli.HibernateUtils;

public class TreeNodeDao {

	/**
	 * 查詢節點
	 * @param treeNode
	 * @return
	 */
	public TreeNode getTreeNode(TreeNode treeNode) {
	     
		Session session = HibernateUtils.openSession();
		TreeNode nd = session.get(TreeNode.class, treeNode.getTreeNodeId());
		
		if(nd!=null&& new Integer(1).equals(treeNode.getInitTreeNode())) {
			Hibernate.initialize(nd.getTreeNodes());
		}

		//呼叫提交事務,關閉session的方法
		HibernateUtils.closesessionn();
		
		return nd;
	}
	
	
	
	
	
	
}

  1. 測試
public class TreeNodeDaoTest {

	private TreeNodeDao dao=new TreeNodeDao();
	
	@Test
	public void testGetTreeNode() {
		TreeNode treeNode=new TreeNode();
		treeNode.setTreeNodeId(1);   //節點Id
		treeNode.setInitTreeNode(1); //設定立即載入 
		TreeNode nd = this.dao.getTreeNode(treeNode);
		
		for(TreeNode n:nd.getTreeNodes()) {
			System.out.println(n.getTreeNodeName());
		
		
		}
			System.out.println(nd);
	}

}

  1. 結果
字典管理
使用者管理
角色管理
許可權管理
TreeNode [TreeNodeId=1, TreeNodeName=系統管理, TreeNodeType=1, position=1, parentNodeId=null, url=null, treeNodes=[TreeNode [TreeNodeId=3, TreeNodeName=字典管理, TreeNodeType=2, position=3, parentNodeId=1, url=null, treeNodes=[]], TreeNode [TreeNodeId=4, TreeNodeName=使用者管理, TreeNodeType=2, position=4, parentNodeId=1, url=null, treeNodes=[]], TreeNode [TreeNodeId=5, TreeNodeName=角色管理, TreeNodeType=2, position=5, parentNodeId=1, url=null, treeNodes=[]], TreeNode [TreeNodeId=6, TreeNodeName=許可權管理, TreeNodeType=1, position=6, parentNodeId=1, url=null, treeNodes=[TreeNode [TreeNodeId=10, TreeNodeName=使用者分配角色, TreeNodeType=2, position=10, parentNodeId=6, url=null, treeNodes=[]], TreeNode [TreeNodeId=11, TreeNodeName=角色授予使用者, TreeNodeType=2, position=11, parentNodeId=6, url=null, treeNodes=[]]]]]]

附: 資料庫表


-- 一對多雙向自關聯
-- 選單表
-- t_hibernate_sys_tree_node
-- t:表
-- sys:模組名縮寫(system)
-- tree_noe:表名
create table t_hibernate_sys_tree_node
(
  tree_node_id int primary key auto_increment,                                                 -- ID
  tree_node_name varchar(50) not null,                                                         -- 名字
  tree_node_type int not null check(tree_node_type = 1 or tree_node_type = 2),                 -- 節點型別:1 枝節點 2 葉節點

  position int,                                                                             -- 位置
  parent_node_id int,                                                                         -- 父節點ID
  url varchar(1024),                                                                           -- URL
  foreign key(parent_node_id) references t_hibernate_sys_tree_node(tree_node_id)
);


-- drop table t_hibernate_sys_tree_node
-- select * from t_hibernate_sys_tree_node


select * from t_hibernate_sys_tree_node;
truncate table t_hibernate_sys_tree_node;


insert into t_hibernate_sys_tree_node(tree_node_id, tree_node_name, tree_node_type, position, parent_node_id, url)
  values(1,'系統管理',1, 1,null,null);
insert into t_hibernate_sys_tree_node(tree_node_id, tree_node_name, tree_node_type, position, parent_node_id, url)
  values(2,'市場管理',1, 2,null,null);

insert into t_hibernate_sys_tree_node(tree_node_id, tree_node_name, tree_node_type, position, parent_node_id, url)
  values(3,'字典管理',2, 3,1,null);
insert into t_hibernate_sys_tree_node(tree_node_id, tree_node_name, tree_node_type, position, parent_node_id, url)
  values(4,'使用者管理',2, 4,1,null);
insert into t_hibernate_sys_tree_node(tree_node_id, tree_node_name, tree_node_type, position, parent_node_id, url)
  values(5,'角色管理',2, 5,1,null);
insert into t_hibernate_sys_tree_node(tree_node_id, tree_node_name, tree_node_type, position, parent_node_id, url)
  values(6,'許可權管理',1, 6,1,null);

insert into t_hibernate_sys_tree_node(tree_node_id, tree_node_name, tree_node_type, position, parent_node_id, url)
  values(7,'進貨管理',2, 7,2,null);
insert into t_hibernate_sys_tree_node(tree_node_id, tree_node_name, tree_node_type, position, parent_node_id, url)
  values(8,'銷售管理',2, 8,2,null);
insert into t_hibernate_sys_tree_node(tree_node_id, tree_node_name, tree_node_type, position, parent_node_id, url)
  values(9,'庫存管理',2, 9,2,null);

insert into t_hibernate_sys_tree_node(tree_node_id, tree_node_name, tree_node_type, position, parent_node_id, url)
  values(10,'使用者分配角色',2, 10,6,null);
insert into t_hibernate_sys_tree_node(tree_node_id, tree_node_name, tree_node_type, position, parent_node_id, url)
  values(11,'角色授予使用者',2, 11,6,null);