Blog信息 |
blog名称: 日志总数:1304 评论数量:2242 留言数量:5 访问次数:7601432 建立时间:2006年5月29日 |

| |
[Hibernate]一个简单的复合主键的做关联类的例子 软件技术
lhwork 发表于 2007/2/2 16:09:24 |
场景是这样的:
用户类User,物品类Goods,每次记录用户使用物品的情况,情况包括谁在什么时间借了什么物品。其中有一个约束条件就是用户只能对同一物品使用一次。使用记录类为Record类。我们可以看出User对Record是1:n多的关系,Record对Goods是n:1的关系,而User和Goods之间没有之间的关系。
RecordId类是复合主键类,分别以n:1关联User类,n:1关联Goods类。RecordId类需要实现equals方法,需要实现Serializable。而Record类用RecordId来做主键。
类定义如下:
java代码
/*
* Created on 2004-10-20
*
*/
package com.javaeye;
import java.util.Calendar;
import java.util.HashSet;
import java.util.Set;
/**
* @author robbin
*
*/
public class User {
private Long id;
private String name;
private Set usingRecords = new HashSet();
/**
* @return Returns the id.
*/
public Long getId() {
return id;
}
/**
* @param id
* The id to set.
*/
public void setId(Long id) {
this.id = id;
}
/**
* @return Returns the name.
*/
public String getName() {
return name;
}
/**
* @param name
* The name to set.
*/
public void setName(String name) {
this.name = name;
}
/**
* @return Returns the usingRecords.
*/
public Set getUsingRecords() {
return usingRecords;
}
/**
* @param usingRecords
* The usingRecords to set.
*/
public void setUsingRecords(Set usingRecords) {
this.usingRecords = usingRecords;
}
public void useGoods(Goods goods) {
RecordId id = new RecordId();
id.setUser(this);
id.setGoods(goods);
Record record = new Record();
record.setRecordId(id);
record.setRecordTime(Calendar.getInstance());
usingRecords.add(record);
}
public void removeRecord(Record record) {
usingRecords.remove(record);
}
}
java代码
/*
* Created on 2004-10-20
*
*/
package com.javaeye;
import java.util.HashSet;
import java.util.Set;
/**
* @author robbin
*
*/
public class Goods {
private Long id;
private String name;
private Set usedRecords = new HashSet();
/**
* @return Returns the id.
*/
public Long getId() {
return id;
}
/**
* @param id
* The id to set.
*/
public void setId(Long id) {
this.id = id;
}
/**
* @return Returns the name.
*/
public String getName() {
return name;
}
/**
* @param name
* The name to set.
*/
public void setName(String name) {
this.name = name;
}
/**
* @return Returns the usedRecords.
*/
public Set getUsedRecords() {
return usedRecords;
}
/**
* @param usedRecords
* The usedRecords to set.
*/
public void setUsedRecords(Set usedRecords) {
this.usedRecords = usedRecords;
}
}
java代码
/*
* Created on 2004-10-20
*
*/
package com.javaeye;
import java.io.Serializable;
/**
* @author robbin
*
*/
public class RecordId implements Serializable {
private User user;
private Goods goods;
/**
* @return Returns the goods.
*/
public Goods getGoods() {
return goods;
}
/**
* @param goods
* The goods to set.
*/
public void setGoods(Goods goods) {
this.goods = goods;
}
/**
* @return Returns the user.
*/
public User getUser() {
return user;
}
/**
* @param user
* The user to set.
*/
public void setUser(User user) {
this.user = user;
}
public boolean equals(Object obj) {
return (obj instanceof RecordId)
&& (this.getUser().equals(((RecordId) obj).getUser()))
&& (this.getGoods().equals(((RecordId) obj).getGoods()));
}
public int hashCode() {
return this.getUser().hashCode() ^ this.getGoods().hashCode();
}
}
java代码
/*
* Created on 2004-10-20
*
*/
package com.javaeye;
import java.util.Calendar;
/**
* @author robbin
*
*/
public class Record {
private RecordId recordId;
private Calendar recordTime;
/**
* @return Returns the recordId.
*/
public RecordId getRecordId() {
return recordId;
}
/**
* @param recordId
* The recordId to set.
*/
public void setRecordId(RecordId recordId) {
this.recordId = recordId;
}
/**
* @return Returns the recordTime.
*/
public Calendar getRecordTime() {
return recordTime;
}
/**
* @param recordTime
* The recordTime to set.
*/
public void setRecordTime(Calendar recordTime) {
this.recordTime = recordTime;
}
} 映射文件配置如下:代码
<?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>
<class name="com.javaeye.User">
<id name="id" unsaved-value="null">
<generator class="native"/>
</id>
<property name="name"/>
<set name="usingRecords" inverse="true" lazy="true" cascade="all-delete-orphan">
<key column="user_id" />
<one-to-many class="com.javaeye.Record"/>
</set>
</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>
<class name="com.javaeye.Goods">
<id name="id" unsaved-value="null">
<generator class="native"/>
</id>
<property name="name"/>
<set name="usedRecords" inverse="false" lazy="true" cascade="all-delete-orphan">
<key column="goods_id" />
<one-to-many class="com.javaeye.Record"/>
</set>
</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>
<class name="com.javaeye.Record">
<composite-id name="recordId" class="com.javaeye.RecordId" unsaved-value="any" >
<key-many-to-one name="user" column="user_id" class="com.javaeye.User" />
<key-many-to-one name="goods" column="goods_id" class="com.javaeye.Goods" />
</composite-id>
<property name="recordTime" type="calendar"/>
</class>
</hibernate-mapping> 记录物品使用情况的代码书写如下:java代码
Goods goods = new Goods();
goods.setName("book");
s.save(goods);
User user = new User();
user.setName("robbin");
s.save(user);
// 用户使用物品
user.useGoods(goods);
当用户重复使用物品的时候,调用userGoods方法,Hibernate会抛出主键重复的错误。判断用户是否使用某物品的办法如下:java代码
RecordId id = new RecordId();
id.setUser(user);
id.setGoods(goods);
Record record = (Record) session.get(Record.class, id);
if (record == null) {
user.usGoods(goods);
} else {
throw new UsedGoodsException("...");
}
然而需要指出的是,Gavin King并不提倡使用composite-id,如果你不是基于已有的数据库编程,而是重新设计数据库结构,那么建议使用UserType。你可以自定义一个UserType,包括User和Goods,并且在hbm中定义该UserType为unique的,同样可以达到目的。而这种方式的好处则是不需要你来手工维护id,而由Hibernate自动维护。UserType的使用方法参考手册5.2.4节和Hibernate自带的示例中的net.sf.hibernate.test.DoubleStringType。 |
|
回复:一个简单的复合主键的做关联类的例子 软件技术
巾盐(游客)发表评论于2008/3/26 13:00:07 |
那么请问一下,如果我现在有以下需求,该如何操作?
需求: 通过表Record中的属性recordTime来查询表User或表Good中关联的另一张或多张表中的信息,如何返回一个完整的List对象呢?难道只能先将每张表对象查询出来,然后再去组装成另外一个List<Object>对象吗?我希望的是只要一个查询语句就搞定这样一个查询,呵呵!要达到这样的效果是否只能另加一张关联多张表的主键的表啊?
殷切期望您的指教,非常感谢!!!
指教回复方式,因为我暂无blog,所以您可回复于我的51中或直接回复,谢谢,希望以后多多交流...
51地址:http://daisyismyname.51.com |
|
回复:一个简单的复合主键的做关联类的例子 软件技术
巾盐(游客)发表评论于2008/3/26 12:06:32 |
那么请问一下,如果我现在有以下需求,该如何操作?
需求: 通过表Record中的属性recordTime来查询表User或表Good中的另一个关联表中的信息
殷切期望您的指教,非常感谢!!!
指教回复方式,因为我暂无blog,所以您可回复于我的51中或直接回复,谢谢,希望以后多多交流...
51地址:http://daisyismyname.51.com |
|
回复:一个简单的复合主键的做关联类的例子 软件技术
test(游客)发表评论于2007/3/8 16:24:22 |
|
» 1 »
|