`
thingkau
  • 浏览: 74609 次
  • 性别: Icon_minigender_1
  • 来自: 泉州
社区版块
存档分类
最新评论

用Hibernate构造和遍历递归树

阅读更多
1.树由节点Node组成,拥有孩子|父亲|节点深度|是否为叶子节点 等属性。

package com.bjsxt.hibernate;

import java.util.Set;
/**
 * 
 * @hibernate.class table="T_Node"
 */
public class Node {

	/**
	 * 标识符
	 * @hibernate.id generator-class="native"
	 */
	private int id;

	
	/**
	 * 节点名称
	 * @hibernate.property
	 */
	private String name;

	/**
	 * 层次
	 * @hibernate.property
	 */
	private int level;

	/**
	 * 是否叶子节点
	 * @hibernate.property
	 */
	private boolean leaf;

	/**
	 * 父节点 * --- 1
	 * @hibernate.many-to-one
	 * 		column="pid"
	 */
	private Node parent;

	
	/**
	 * 子节点 1 --- *
	 * @hibernate.set
	 * 		inverse="true" lazy="extra"
	 * @hibernate.key
	 * 		column="pid"
	 * @hibernate.one-to-many class="com.bjsxt.hibernate.Node"
	 */
	private Set children;

	public Set getChildren() {
		return children;
	}

	public void setChildren(Set children) {
		this.children = children;
	}

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public boolean isLeaf() {
		return leaf;
	}

	public void setLeaf(boolean leaf) {
		this.leaf = leaf;
	}

	public int getLevel() {
		return level;
	}

	public void setLevel(int level) {
		this.level = level;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public Node getParent() {
		return parent;
	}

	public void setParent(Node parent) {
		this.parent = parent;
	}
}



配合XDOCLET+ANT生成hibernate的映射文件Node.xml如下:

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
    <class name="com.bjsxt.hibernate.Node" table="T_Node">
        <id name="id">
            <generator class="native"/>
        </id>
        <property name="name"/>
        <property name="level"/>
        <property name="leaf"/>
        <many-to-one name="parent" column="pid"/>
        <set name="children" inverse="true" lazy="extra">
        <key column="pid"/>
        <one-to-many class="com.bjsxt.hibernate.Node"/>
        </set>
    </class>
</hibernate-mapping>

2.构造和遍历递归树保存于数据库中:
NodeManager.java
package com.bjsxt.hibernate;

import java.io.File;
import java.util.Iterator;
import java.util.Set;

import org.hibernate.Session;

public class NodeManager {

	private static NodeManager nodeManager;

	private NodeManager() {
	}
 
	public static synchronized NodeManager getInstance() {
		if (nodeManager == null) {
			nodeManager = new NodeManager();
		}

		return nodeManager;
	}

	// 创建树型结构
	public void createTree(String dir) {
		Session session = HibernateUtils.getSession();

		try {
			session.beginTransaction();

			File root = new File(dir);
			saveTree(root, session, null, 0);

			session.getTransaction().commit();
		} catch (RuntimeException e) {
			e.printStackTrace();
			session.getTransaction().rollback();
		} finally {
			HibernateUtils.closeSession(session);
		}
	}

	
	/**
	 * 递归创建一棵树
	 * @param file 		文件实例
	 * @param session 	HiernateSession
	 * @param parent	父节点
	 * @param level		节点深度
	 */
	private void saveTree(File file, Session session, Node parent, int level) {

		if (file == null || !file.exists()) {
			return;
		}

		boolean isLeaf = file.isFile();

		Node node = new Node();
		node.setName(file.getName());
		node.setLevel(level);
		node.setParent(parent);
		node.setLeaf(isLeaf);
		session.save(node);

		File[] subs = file.listFiles();
		if (subs != null && subs.length > 0) {
			for (int i = 0; i < subs.length; i++) {
				saveTree(subs[i], session, node, level + 1);
			}
		}
	}

	public void printTree(int id) {
		Session session = HibernateUtils.getSession();

		try {
			session.beginTransaction();

			Node root = (Node) session.load(Node.class, id);
			printNode(root);

			session.getTransaction().commit();
		} catch (RuntimeException e) {
			e.printStackTrace();
			session.getTransaction().rollback();
		} finally {
			HibernateUtils.closeSession(session);
		}
	}

	/**
	 * 打印节点【打印结果是树形结构】
	 * @param node 节点实例
	 */
	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);
		}
	}
}



3.客户端调用:
新建一测试用例:NodeManagerTest.java:
package com.bjsxt.hibernate;

import junit.framework.TestCase;

public class NodeManagerTest extends TestCase {

	public void testCreateTree() {
		NodeManager.getInstance().createTree("E:\\200809050031\\hibernate\\hibernate_training_tree\\");
	}
   
	public void testPrintTree() {
		NodeManager.getInstance().printTree(1);
	}

}


保证实现已经创建好hibernate配置文件和数据库,打印出来的结果:

hibernate_training_tree[5]
  |--readme.txt
  |--.project
  |--bin[3]
  |  |--log4j.properties
  |  |--com[1]
  |  |  |--bjsxt[1]
  |  |  |  |--hibernate[6]
  |  |  |  |  |--HibernateUtils.class
  |  |  |  |  |--Node.hbm.xml
  |  |  |  |  |--NodeManager.class
  |  |  |  |  |--Node.class
  |  |  |  |  |--NodeManagerTest.class
  |  |  |  |  |--ExportToDB.class
  |  |--hibernate.cfg.xml
  |--.classpath
  |--src[3]
  |  |--hibernate.cfg.xml
  |  |--com[1]
  |  |  |--bjsxt[1]
  |  |  |  |--hibernate[6]
  |  |  |  |  |--Node.java
  |  |  |  |  |--NodeManager.java
  |  |  |  |  |--NodeManagerTest.java
  |  |  |  |  |--HibernateUtils.java
  |  |  |  |  |--Node.hbm.xml
  |  |  |  |  |--ExportToDB.java
  |  |--log4j.properties

分享到:
评论
发表评论

文章已被作者锁定,不允许评论。

相关推荐

    Java 开发JSP无限级分类目录树-sorttree项目源码

    对于无限级分类目录树,遍历和操作(如添加、删除、移动节点)可能需要递归算法,确保操作正确地影响整个树。 8. 状态保持: 如果应用需要记住用户的展开状态,可以使用cookies、session或者前端的local storage...

    JAVA+Hibernate 无限级分类

    总的来说,利用Hibernate和Java实现无限级分类,需要理解树形结构的数据模型,自定义额外的属性以辅助表示层次关系,以及有效地执行递归查询来处理层级数据。在实际应用中,这样的设计可以灵活地扩展和维护复杂的...

    java面试题.zip

    - 构造器:知道何时使用构造器,以及构造器的重载。 - 访问修饰符:public, private, protected和默认的访问级别。 - 继承与多态:了解单继承、接口实现多继承、抽象类和接口的使用。 - 封装:理解封装的概念,...

    reflection模拟JavaBean.rar

    4. **遍历类的继承层次**:使用`Class.getSuperclass()`获取父类,递归处理以实现类的深度遍历。 此外,反射还常用于以下场景: - **框架开发**:Spring、Hibernate等框架大量使用反射进行依赖注入和数据库操作。 -...

    12-java软件工程师(初级)笔试题.pdf

    先序遍历是指首先访问根节点,然后递归地进行左子树的先序遍历,最后进行右子树的先序遍历。 在日常开发中,开发者可能会遇到各种棘手的问题,比如内存泄漏、系统性能瓶颈、并发问题、框架使用不当、难以复现的bug...

    swing界面设计之JTree

    - **如何遍历JTree**:使用递归算法或`Enumeration`接口遍历树中的每个节点。 #### (四) JTree的使用方法 **JTreeDemo.java源程序**:示例代码展示了如何创建并使用JTree。 - **经验汇总**:列举了一系列实用技巧...

    Java持久化数据结构详解.pdf

    这个类有两个属性:`price`(价格)和`onward`(指向下一个旅程的引用),以及一个构造函数来初始化这些属性。`onward` 属性创建了一个链表结构,可以表示一系列连续的火车旅程。 代码中的 `link()` 函数用于连接两...

    JSP分页技术-让你不同体验

    在JSP页面上,可以使用JSTL(JavaServer Pages Standard Tag Library)的`c:forEach`标签遍历分页数据,并展示在表格或其他元素中。同时,还需要创建上一页、下一页、首页和末页的链接,以便用户导航。链接中的页码...

    java面试题及答案-非常全面(包括基础、网络、数据结构、算法及IT大厂面经)

    - **非阻塞I/O**:与传统的`InputStream`/`OutputStream`不同,使用`Channel`和`Buffer`。 - **特性**:提供更高效的文件传输和网络通信能力。 - **核心组件**:`Selector`用于监控多个通道的事件。 ### JAVA反射 ...

    java私塾全部笔记

    - 方法重载和递归。 ##### 第三章 Java类和对象 - **类的概念** - 类是对象的蓝图,定义了一组相似对象的共同特征。 - **对象实例化** - 如何创建类的实例对象。 - 对象的引用和内存分配。 - **构造器** - ...

    自动校验工程源码

    4. **迭代与递归遍历**:在自动校验过程中,我们需要遍历整个对象图,包括嵌套的对象和集合。这通常涉及迭代和递归,以确保所有层次的字段都经过校验。 5. **异常处理**:当校验失败时,应当抛出适当的异常,如`...

    javase相关知识点

    3. 树型表结构:通常需要id(主键)、parent_id(父节点id)字段,通过递归查询构建树形结构。 4. SQL查询:SELECT Sname, SUM(Ccredit) FROM Student JOIN SC ON Student.Sno = SC.Sno JOIN Course ON SC.Cno = ...

    为了高效地将Json对象转化成Java bean对象,传统上我们是在运行是利用反射来实现.zip

    在Java开发中,将JSON对象转化为Java Bean对象是一项常见的任务,特别是在处理Web服务或网络通信时。...对于大型项目,考虑使用ORM框架如Hibernate或MyBatis,它们通常有内置的JSON处理机制,可以进一步简化转换过程。

    java基础,面试题

    5. **方法**:了解方法的定义,参数传递(按值传递,按引用传递),返回值,重载和递归。 6. **数组**:理解一维、二维数组的创建、遍历和操作。 7. **面向对象**:封装,继承,多态是Java的三大特性。要熟悉类,...

    Java机试相关题目34题

    28. Struts和Hibernate框架实现:本题涉及Web开发中Struts和Hibernate框架的使用,需要建立数据库表,并通过框架实现业务逻辑。 以上内容涉及到了Java编程的多个关键领域,包括设计模式、类设计、数据结构、算法、...

    java高级工程师面试总结

    - **final关键字的使用和区别**: - 当应用于变量时,`final`表示该变量一旦被初始化就不能更改其值。 - 当应用于方法时,`final`表示该方法不能被子类覆盖。 - 当应用于类时,`final`表示该类不能被继承。 - **...

    Java笔试训练题锦集

    - ORM框架:Hibernate, MyBatis的基本使用。 通过深入学习和练习这些知识点,不仅可以提升你的Java笔试能力,还能为面试做好充分准备,从而在竞争激烈的IT行业中脱颖而出。记得理论结合实践,不断巩固和深化理解。

    JAVA面试笔试题

    总结起来,本篇文章涵盖了Java面试笔试题中的多个重要知识点,包括排序算法、集合框架、多线程、设计模式、数据库连接、XML应用、Hibernate分页以及JavaScript和Ajax的基本使用等。这些知识点不仅对初学者来说非常...

    java源码包---java 源码 大量 实例

    递归遍历矩阵 1个目标文件,简单! 多人聊天室 3个目标文件 第一步:运行ServerData.java 启动服务器,然后服务器处于等待状态 第二步:运行LoginData.java 启动(客户端)登陆界面 输入用户名 ip为本机localhost 第...

    java源码包2

    递归遍历矩阵 1个目标文件,简单! 多人聊天室 3个目标文件 第一步:运行ServerData.java 启动服务器,然后服务器处于等待状态 第二步:运行LoginData.java 启动(客户端)登陆界面 输入用户名 ip为本机localhost...

Global site tag (gtag.js) - Google Analytics