本站首页    管理页面    写新日志    退出


«August 2025»
12
3456789
10111213141516
17181920212223
24252627282930
31


公告
本博客在此声明所有文章均为转摘,只做资料收集使用。并无其他商业用途。

我的分类(专题)

日志更新

最新评论

留言板

链接

Blog信息
blog名称:
日志总数:210
评论数量:205
留言数量:-19
访问次数:919686
建立时间:2007年5月10日




[Hibernate]一个简单的复合主键的做关联类的例子
文章收藏,  网上资源,  软件技术,  电脑与网络

李小白 发表于 2007/7/19 10:42:54

  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。


阅读全文(1568) | 回复(0) | 编辑 | 精华
 



发表评论:
昵称:
密码:
主页:
标题:
验证码:  (不区分大小写,请仔细填写,输错需重写评论内容!)



站点首页 | 联系我们 | 博客注册 | 博客登陆

Sponsored By W3CHINA
W3CHINA Blog 0.8 Processed in 0.199 second(s), page refreshed 144792430 times.
《全国人大常委会关于维护互联网安全的决定》  《计算机信息网络国际联网安全保护管理办法》
苏ICP备05006046号