026 hibernate操作树形结构

树形结构:也就是目录结构,有父目录、子目录、文件等信息,而在程序中树形结构只是称为节点。

一棵树有一个根节点,而根节点也有一个或多个子节点,而一个子节点有且仅有一个父节点(当前除根节点外),而且也存在一个或多个子节点。

也就是说树形结构,重点就是节点,也就是我们需要关心的节点对象。

节点:一个节点有一个ID、一个名称、它所属的父节点(根节点无父节点或为null),有一个或多的子节点等其它信息。

Hibernate将节点抽取出成实体类,节点相对于父节点是“多对一”映射关系,节点相对于子节点是“一对多”映射关系。  

节点实体类:

/** * 节点*/

public class Node {

private int id; //标识符

private String name; //节点名称

private int level; //层次,为了输出设计

private boolean leaf; //是否为叶子节点,这是为了效率设计,可有可无

    //父节点:因为多个节点属于一个父节点,因此用hibernate映射关系说是多对一

private Node parent;

    //子节点:因为一个节点有多个子节点,因此用hibernate映射关系说是一对多

private Set children;

public int getId() {

return id;

}

public void setId(int id) {

this.id = id;

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public int getLevel() {

return level;

}

public void setLevel(int level) {

this.level = level;

}

public boolean isLeaf() {

return leaf;

}

public void setLeaf(boolean leaf) {

this.leaf = leaf;

}

public Node getParent() {

return parent;

}

public void setParent(Node parent) {

this.parent = parent;

}

public Set getChildren() {

return children;

}

public void setChildren(Set children) {

this.children = children;

}

}

节点映射文件:

<hibernate-mapping>

<class name="com.wjt276.hibernate.Node" table="t_node">

<id name="id" column="id">

<generator class="native"/>

</id>

<property name="name"/>

<property name="level"/>

<property name="leaf"/>

<!— 一对多:加入一个外键,参照当前表t_node主键

而属性parent类型为Node,也就是当前类,则会在同一个表中加入这个字段,参照这个表的主键-->

<many-to-one name="parent" column="pid"/>

<!-- <set>标签是映射一对多的方式,加入一个外键,参照主键。-->

<set name="children" lazy="extra" inverse="true">

<key column="pid"/>

<one-to-many class="com.wjt276.hibernate.Node"/>

</set>

</class>

</hibernate-mapping>

测试代码:

public class NodeTest extends TestCase {

//测试节点的存在

public void testSave1(){

NodeManage.getInstanse().createNode("F:\\JAVA\\JavaProject\\hibernate\\hibernate_training_tree");

}

//测试节点的加载

public void testPrintById(){

NodeManage.getInstanse().printNodeById(1);

}

}

相应的类代码:

public class NodeManage {

private static NodeManage nodeManage= new NodeManage();

private NodeManage(){}//因为要使用单例,所以将其构造方法私有化

//向外提供一个接口

public static NodeManage getInstanse(){

return nodeManage;

}

/**

* 创建树

* @param filePath 需要创建树目录的根目录

*/

public void createNode(String dir) {

Session session = null;

try {

session = HibernateUtils.getSession();

session.beginTransaction();

File root = new File(dir);

//因为第一个节点无父节点,因为是null

this.saveNode(root, session, null, 0);

session.getTransaction().commit();

} catch (HibernateException e) {

e.printStackTrace();

session.getTransaction().rollback();

} finally {

HibernateUtils.closeSession(session);

}

}

/**

* 保存节点对象至数据库

* @param file 节点所对应的文件

* @param session session

* @param parent 父节点

* @param level 级别

*/

public void saveNode(File file, Session session, Node parent, int level) {

if (file == null || !file.exists()){

return;

}

//如果是文件则返回true,则表示是叶子节点,否则为目录,非叶子节点

boolean isLeaf = file.isFile();

Node node = new Node();

node.setName(file.getName());

node.setLeaf(isLeaf);

node.setLevel(level);

node.setParent(parent);

session.save(node);

//进行循环迭代子目录

File[] subFiles = file.listFiles();

if (subFiles != null && subFiles.length > 0){

for (int i = 0; i < subFiles.length ; i++){

this.saveNode(subFiles[i], session, node, level + 1);

}

}

}

/**

* 输出树结构

* @param id

*/

public void printNodeById(int id) {

Session session = null;

try {

session = HibernateUtils.getSession();

session.beginTransaction();

Node node = (Node)session.get(Node.class, 1);

printNode(node);

session.getTransaction().commit();

} catch (HibernateException e) {

e.printStackTrace();

session.getTransaction().rollback();

} finally {

HibernateUtils.closeSession(session);

}

}

private void printNode(Node node) {

if (node == null){

return;

}

int level = node.getLevel();

if (level > 0){

for (int i = 0; i < level; i++){

System.out.print("  |");

}

System.out.print("--");

}

System.out.println(node.getName() + (node.isLeaf() ? "" : "[" + node.getChildren().size() + "]"));

Set children = node.getChildren();

for (Iterator iter = children.iterator(); iter.hasNext(); ){

Node child = (Node)iter.next();

printNode(child);

}

}

}

时间: 2024-08-09 04:04:24

026 hibernate操作树形结构的相关文章

Hibernate中,基于Annotation的简单树形结构的实现

在系统设计中,经常用到递归性质的树形结果,比如菜单.多级分类等,一般是在同一个表中定义父子关系实现这种结构. 下面是在Hibernate中,基于Annotation的简单树形结构的实现: 第一步:创建Entity类,并添加注解实现关联关系    ps: 主要是利用@ManyToOne 和 @OneToMany 配置在同一个Entity类中实现树形递归的结构.hibernate注解形式比在xml配置更加简洁 TreeNode.java 1 package com.hfut.hibernate; 2

java工程积累——树形结构的操作

最近一直被树形结构整的很头大,又是递归,又是循环,但是,好在我们在经历了千辛万苦后,终于弄出来了,其实就是组织机构的常规操作,有些是我们过度设计,有些是我们想错了,而对数的逻辑读取,我们就属于想错了的类型,今天拿出来和大家分享,主要是树形结构在数据库的读取问题! 原始: 在最开始,我们对树的查询,肯定是从最简单的select开始,我们现在回顾一下: 定义: 表名:tb_tree 字段:id(主键),title(标题),parentId(父节点id) 举例: 1.查找树中的所有顶级父节点(辈份最长

javaproject积累——树形结构的操作

近期一直被树形结构整的非常头大,又是递归.又是循环.可是,好在我们在经历了千辛万苦后.最终弄出来了.事实上就是组织机构的常规操作,有些是我们过度设计.有些是我们想错了.而对数的逻辑读取,我们就属于想错了的类型.今天拿出来和大家分享.主要是树形结构在数据库的读取问题! 原始: 在最開始.我们对树的查询,肯定是从最简单的select開始.我们如今回想一下: 定义: 表名:tb_tree 字段:id(主键),title(标题),parentId(父节点id) 举例: 1.查找树中的全部顶级父节点(辈份

【DRP】树形结构操作之递归删除

如图所示呈现了一颗树形结构.本文从删除树形结构的任意结点出发,提供了一种解决思路 图中,不包含其它结点的是叶子结点.包含其他结点的是父结点,即不是叶子结点. 一 本文的知识点: (1)递归调用: 因为待删除的结点的层次是不确定的,如果是叶子结点则可以直接获取id直接删除,如:北京中医医院.华北区.如果待删除的结点是父结点,则需要继续向下查询,依次遍历出其子结点,从下往上依次删除,如'华北区'.因此我们使用递归调用. (2)保证事务的原子性 假设待删除的结点是'华北区',则相当于删除了3条信息(华

Qt QTreeWidget 树形结构实现(转)

Qt中实现树形结构可以使用QTreeWidget类,也可以使用QTreeView类,QTreeWidget继承自QTreeView类.树形效果如下图所示: 这是怎么实现的呢?还有点击节点时会有相应的事件响应. 1. 树形结构实现 QT GUI中有treeWidget部件,将该控件在Gui中布局好,假设其对象名为treeWidget. QTreeWidget类官方文档:http://qt-project.org/doc/qt-4.8/qtreewidget.html 树形结构通过QTreeWidg

salesforce 零基础学习(七十)使用jquery tree实现树形结构模式

项目中UI需要用到树形结构显示内容,后来尽管不需要做了,不过还是自己做着玩玩,mark一下,免得以后项目中用到. 实现树形结构在此使用的是jquery的dynatree.js.关于dynatree的使用可以参考:http://wwwendt.de/tech/dynatree/doc/dynatree-doc.html#h4.2 对于树形结构,这里不做太多介绍,树一般需要一个根节点,根节点下面可以有很多子节点或者叶子节点,子结点也可以包含叶子结点或者子节点.我们在设计表结构的时候可以考虑自连接操作

Delphi中根据分类数据生成树形结构的最优方法

一. 引言:    TreeView控件适合于表示具有多层次关系的数据.它以简洁的界面,表现形式清晰.形象,操作简单而深受用户喜爱.而且用它可以实现ListView.ListBox所无法实现的很多功能,因而受到广大程序员的青睐.    树形结构在Windows环境中被普遍应用,但在数据库开发中面对层次多.结构复杂的数据,如何快速构造树形目录并实现导航呢?    二. 实现关键技术:    在Delphi提供的控件中包含了TreeView控件,但树的具体形成还需要用户编写代码.即它的列表项要在程序

树形结构的数据库的存储

程序设计过程中,我们常常用树形结构来表征某些数据的关联关系,如企业上下级部门.栏目结构.商品分类等等,通常而言,这些树状结构需要借助于数据库完成持久化.理想中树形结构应该具备如下特征:数据存储冗余度小.直观性强:检索遍历过程简单高效:节点增删改查CRUD操作高效. 列举了一个食品族谱的例子进行讲解,通过类别.颜色和品种组织食品,树形结构图如下: 1,对树形结构最直观的分析莫过于节点之间的继承关系上,通过显示地描述某一节点的父节点,从而能够建立二维的关系表,则这种方案的Tree表结构通常设计为:{

【树形结构】zTree

树形结构有多种形式和实现方式,zTree可以说得上是一种比较简洁又美观的且实现起来也相对简单.zTree是一个依靠jQuery实现的多功能"树插件".它最大的优点是配置灵活,只要id与pid的值相同就可形成一个简单的父子结构.再加上免费开源,使用zTree的人越来越多. 一.概述 1.实现思路 假设有两张表:A表.B表,如果B.Id=A.PId,则A与B将可构成树形结构. (Id与PId只是两种表示,数据库中不一定是这两个字段.其实一张表也完全可以形成树形结构,不过这样就有点凌乱了..