Hibernate:组合模式解决树的映射

时间:2023-03-09 15:10:51
Hibernate:组合模式解决树的映射

树经常用来展示目录结构,那么在Hibernate中怎样解决树的映射问题呢?

先来看一个分销商的树形结构的例子


所有分销商

东北区

辽宁省

沈阳医药

吉林省

华北区

北京市

北京医药

河北省

华南区

那么怎样用组合模式抽象这一模型呢?

先看下类图

Hibernate:组合模式解决树的映射

大家都知道树的存储可以有两种方式

双亲存储

每一个节点都存储它的直接父节点的地址

孩子存储

每个节点都存储它所有直接孩子节点的地址

但是在对象模型中,我们既想知道节点的父亲是谁又想获取它的所有孩子节点

那么类图可以修改如下

Hibernate:组合模式解决树的映射

上图中,为每个节点都添加了父节点引用,放在Node类中是为了复用

上java代码

抽象Node类

public abstract class Node {

	private String id;

	private String name;
//父节点引用
private Node parent; public String getId() {
return id;
} public void setId(String 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;
} }

Client类

public class Client extends Node {
//分销商级别
private ClientLevel level; public ClientLevel getLevel() {
return level;
} public void setLevel(ClientLevel level) {
this.level = level;
} }

Region类

public class Region extends Node {
//孩子节点集合,只有区域才有可能有孩子节点
private Set children; public Set getChildren() {
return children;
} public void setChildren(Set children) {
this.children = children;
} }

ClientLevel类

public class ClientLevel {

	private String id;

	private String name;

	public String getId() {
return id;
} public void setId(String id) {
this.id = id;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} }

最关键的是HBM映射文件

HBM--ClientLevel

<hibernate-mapping package="com.tgb.hibernate">
<class name="ClientLevel" table="t_client_level">
<id name="id">
<generator class="uuid"/>
</id>
<property name="name"/>
</class> </hibernate-mapping>

HBM--Tree

<hibernate-mapping package="com.tgb.hibernate">
<class name="Node" abstract="true">
<id name="id">
<generator class="uuid"/>
</id>
<property name="name"/>
<many-to-one name="parent" column="pid"/>
<union-subclass name="Region" table="t_region">
<set name="children" inverse="true">
<key column="pid"/>
<one-to-many class="Node"/>
</set>
</union-subclass>
<union-subclass name="Client" table="t_client">
<many-to-one name="level"/>
</union-subclass>
</class>
</hibernate-mapping>

这样就实现了树形结构的映射。