论坛首页 Java版 Hibernate

想要实现可快速访问单个子的一对多关系?

浏览 1687 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
最后更新时间:2005-03-11
想用MAP,其中要能包含使用外键建立的一对多关系,还能从一的一端通过一个CODE(不用KEY)以避免误解。这里的FK对所有子而言都是唯一的,而CODE对具体的父而言,它的各个子的CODE是不同的

看了手册,没专门指,只在“三重关联”中出现了手册中关于MAP的语法详解中的定义不一致的示例:
<map name="contracts" lazy="true">
<key column="employer_id"/>
<dddddindex-many-to-many column="employee_id" class="Employee"/>
<one-to-many column="contract_id" class="Contract"/>
</map>

等元素来定义集合,而<map>是最典型的一个。
<map
name="propertyName"
table="table_name"
schema="schema_name"
lazy="true|false"
inverse="true|false"
cascade="all|none|save-update|delete|all-delete-orphan"
sort="unsorted|natural|comparatorClass"
order-by="column_name asc|desc"
where="arbitrary sql where condition"
outer-join="true|false|auto"
batch-size="N" (11)
access="field|property|ClassName" (12)
>
<key .... />
<ddddindex .... />
<element .... />
</map>
   
最后更新时间:2005-03-11
其实Map/List都不适合做对象之间的关联,Hibernate中有一种值集合,用一个类来映射一对主外键关联的表,这种情况下通常用Map会比较合适。我举一个简单的例子:

我群发短信,记录Log,这个类叫做SmsLog,需要记录发送的手机号码mo,消息message,以及发送到的每个手机号码和发送结果,他就是这样的结构:

[code:1]public class SmsLog {
    private String mo;
    private String message;
    private Map results;
}[/code:1]

只有一个类,但是有两个表,这种情况下使用Map。
   
0 请登录后投票
最后更新时间:2005-03-11
package org.wspsc.hibernate;

import java.util.HashMap;
import java.util.Map;

/**
* @author Administrator
*/
public class Process {
private Long id;
private Map activitys =new HashMap();

public Map getActivitys() {
return activitys;
}
public void setActivitys(Map activitys) {
this.activitys = activitys;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
}



---------------------
package org.wspsc.hibernate;

/**
* @author Administrator
*/
public class Activity {
private Long id;
private String keys;
private Process parent;
private String name;

public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getKeys() {
return keys;
}
public void setKeys(String keys) {
this.keys = keys;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Process getParent() {
return parent;
}
public void setParent(Process parent) {
this.parent = parent;
}
}


---------------

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 2.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd" >

<hibernate-mapping package="org.wspsc.hibernate">
<class name="Process">
<id name="id">
<generator class="increment"/>
</id>
<map name="activitys" cascade="all" inverse="true">
<key column="parent"></key>
<index column="keys" type="string"></index>
<one-to-many class="Activity"/>
</map>
</class>
</hibernate-mapping>

-----------------
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 2.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd" >

<hibernate-mapping package="org.wspsc.hibernate">
<class name="Activity">
<id name="id">
<generator class="increment"/>
</id>
<property name="name"></property>
<property name="keys"></property>
<many-to-one name="parent" class="Process"></many-to-one>
</class>
</hibernate-mapping>


------------------------

package org.wspsc.hibernate.test;

import junit.framework.TestCase;
import net.sf.hibernate.Session;
import net.sf.hibernate.Transaction;

import org.wspsc.hibernate.Activity;
import org.wspsc.hibernate.Process;
import org.wspsc.hibernate.util.HibernateUtil;

/**
* @author Administrator
*/
public class MapTest extends TestCase {

public static void main(String[] args) {
junit.textui.TestRunner.run(MapTest.class);
}

public void testMap()throws Exception{
//HibernateUtil.createSchema();
Session s =HibernateUtil.currentSession();
Transaction tx =s.beginTransaction();
Process p =new Process();
s.save(p);

Activity a =new Activity();
a.setName("activity's name");
a.setKeys("begin");
a.setParent(p);
p.getActivitys().put("begin", a);

Activity b =new Activity();
b.setName("activity's name 2");
b.setKeys("end");
b.setParent(p);
p.getActivitys().put("end", b);

s.saveOrUpdate(p);
tx.commit();
HibernateUtil.closeSession();
s =HibernateUtil.currentSession();
Process pp =(Process)s.get(Process.class, new Long(6));
Activity aa =(Activity)pp.getActivitys().get("end");
System.out.println(aa.getId());
HibernateUtil.closeSession();
}
}
   
0 请登录后投票
最后更新时间:2005-03-11
我又试了一下,可以从从取得的子对象中访问到父。我未配parent标签,说明子不是值对象,这确实是一个可快速访问单个子的父子关系!

我再试了一下,那么关联方面的特性都得到了反映。好象一切都向好的方向发展:)
   
0 请登录后投票
最后更新时间:2005-03-11
到底需求,对象关系是什么?
从楼主给的代码看,并没有什么特别一定要Map的地方啊? 普通的双向一对多关系而已.
   
0 请登录后投票
最后更新时间:2005-03-11
具体的需求我就不说了。主要目标是快速地从父访问子

例如,对于张三,他有2个儿子:大儿子张龙,小儿子张虎。假设我现在已经得到张三,想得到张龙,但我不知道它的主键(PK),如果不象我这样做那么就只能历遍或查询了。

在这里,“大儿子”对于张三而言是唯一的,所以用MAP是比较自然的
   
0 请登录后投票
最后更新时间:2005-03-14
上面的“一对多”中从“一”的一端快速访问“多”的一端的任意对象的方法已经实现

现在正解决“多对多”中从任意一方快速访问另一端的任意对象的问题,原来以为可以从上面的方法中得到一些经验,但实际上好象比第一个问题难度大一些,还没配置成功
   
0 请登录后投票
最后更新时间:2005-03-14
大受打击,都有点怀疑上次配出的东西的稳定性了。手册中有这么一段,它把涉“多”的关联的所有可能都列出来了:

6.9. 双向关联(Bidirectional Associations)
双向关联允许通过关联的任一端访问另外一端。在Hibernate 中, 支持两种类型的双向关联:
一对多(one-to-many)
Set 或者bag 值在一端, 单独值(非集合)在另外一端
多对多(many-to-many)
两端都是set 或bag 值
请注意Hibernate 不支持带有索引的集合(list,map 或者array)作为"多"的那一端的双向oneto-
many 关联。
   
0 请登录后投票
最后更新时间:2005-03-15
把关系映射到两个表就可以啦.
   
0 请登录后投票
论坛首页 Java版 Hibernate

跳转论坛:
JavaEye推荐