使用Hibernate建立树形结构
递归查询子节点,会发出N多次select查询
可以在Node中定义一个字段,额外记录其与parent的id间的关系,如1|3|6|12
然后使用like进行模糊查询,只需要查询1次即可找出所有的child。
虽然模糊查询慢,但只发出1条语句,所以效率可能比发出N多次递归查询快!
实体类
package org.leadfar.hibernate.model; import java.util.Set; public class Node { private int id; private String name; private Node parent; private Set<Node> 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 Node getParent() { return parent; } public void setParent(Node parent) { this.parent = parent; } public Set<Node> getChildren() { return children; } public void setChildren(Set<Node> children) { this.children = children; } }
映射文件
<?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 package="org.hibernate.auction"> <class name="org.leadfar.hibernate.model.Node" table="t_node" > <!-- id为数据库标识,作为主键 --> <id name="id"> <generator class="native"/> </id> <property name="name"/> <many-to-one name="parent" column="pid"> </many-to-one> <set name="children" lazy="extra" inverse="true"> <key column="pid"></key> <one-to-many class="org.leadfar.hibernate.model.Node"></one-to-many> </set> </class> </hibernate-mapping>
测试
package org.leadfar.hibernate.model; import java.io.File; import java.util.Iterator; import java.util.Set; import junit.framework.TestCase; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.cfg.Configuration; public class Test_tree extends TestCase { /** * 建立一个文件目录树。可以根据某个节点查找其父节点,也可以查找其子节点 * 查找父节点--many-to-one * 查找子节点--one-to-many * * 关联关系---parent字段,可以看做是外键 * 从多的一端即孩子端建立关联关系 */ public void tree_save() { Configuration cfg = new Configuration().configure(); SessionFactory sfactory = cfg.buildSessionFactory(); Session session = sfactory.openSession(); try { session.beginTransaction(); save(session,new File("F:\\oracle"),null); session.getTransaction().commit(); } catch(Exception e) { e.printStackTrace(); session.getTransaction().rollback(); } finally { session.close(); } } public void tree_findParent() { Configuration cfg = new Configuration().configure(); SessionFactory sfactory = cfg.buildSessionFactory(); Session session = sfactory.openSession(); try { session.beginTransaction(); Node node = (Node)session.load(Node.class, 2034); find_parent(node); session.getTransaction().commit(); } catch(Exception e) { e.printStackTrace(); session.getTransaction().rollback(); } finally { session.close(); } } public void tree_findChild() { Configuration cfg = new Configuration().configure(); SessionFactory sfactory = cfg.buildSessionFactory(); Session session = sfactory.openSession(); try { session.beginTransaction(); Node node = (Node)session.load(Node.class, 22); find_child(node,0); session.getTransaction().commit(); } catch(Exception e) { e.printStackTrace(); session.getTransaction().rollback(); } finally { session.close(); } } //保存一个文件目录树到数据库---parent记录父子关系 private void save(Session session,File file,Node parent) { Node node = new Node(); node.setName(file.getName()); node.setParent(parent); session.save(node); if(file.exists()) { File[] f = file.listFiles(); if(f!=null && f.length>0) { for(File sub : f) { if(sub.isDirectory()) save(session,sub,node); } } } } //查找给定节点的父节点 private void find_parent(Node node) { System.out.print(node.getName()); Node parent = node.getParent(); if(parent!=null) { System.out.print("-->"); find_parent(parent); } } //给定节点查找其子节点 private void find_child(Node node,int level) { for(int i=0;i<level;i++) { System.out.print("\t"); } System.out.println(node.getName()); Set<Node> childs = node.getChildren(); if(childs.size()!=0) { for(Node n : childs){ find_child(n,level+1); } } } }
相关推荐
Hibernate双向一对一关联映射(注解版)
包含《多对多双向关联映射》《多对一单向关联映射》《多对一双向关联映射》《一对多单向关联映射》等文档,并有图解及例子,非常适合新手学习,尤其是刚刚接触hibernate,对映射关系不清楚的。。。。
Hibernate 多对一外键单向关联 Hibernate 多对一连接表单向关联 Hibernate 多对多单向关联 Hibernate 一对一外键双向关联 Hibernate 一对一主键双向关联 Hibernate 一对一连接表双向关联 Hibernate 一对多外键双向...
hibernate双向一对多关联映射(注解版)
多对多双向关联 <br>注意映射规则: <set name="roles" table="t_user_role"><br> <key column="userid"/><br> <many-to-many class="com.bjsxt.hibernate.Role" column="roleid"/> </set><br> table...
博文链接:https://shaqiang32.iteye.com/blog/201309
hibernate双向多对多关联映射(注解版)
hibernate双向一对多关联映射(XML)
NULL 博文链接:https://fangguanhong.iteye.com/blog/1735492
Hibernate关联关系映射 单向关联 │ ├─ 一对一外键单向关联 │ ├─ 一对一主键单向关联 │ ├─ 一对一连接表单向关联 │ ├─ 一对多外键单向关联 │ ├─ 一对多连接表单向关联 │ ├─ 多对一外键单向关联 │ ...
Hibernate的映射策略:一对一双向关联映射,有所有的测试用例,用以证明从任何一端都可以加载另一端信息。
NULL 博文链接:https://dreamzhong.iteye.com/blog/1200915
hibernate双向多对多关联映射(XML)
1:Hibernate的关联映射,存在一对多和多对一映射,多对多映射: 1.1:一对多和多对一映射,举例说明: 学生和老师: 一个老师可以教多个学生 【一对多映射】 多个学生可以被一个老师教【多对一映射】 部门与员工: ...
NULL 博文链接:https://1028826685.iteye.com/blog/1536060
NULL 博文链接:https://paladin1988.iteye.com/blog/1657564
hibernate外键实现一对一双向关联关系源码
Hibernate映射一对多关联关系
Hibernate双向一对一关联映射(XML版)