Hibernate映像文件详细分析

来源:岁月联盟 编辑:zhuzhu 时间:2009-09-23

本文向大家介绍Hibernate映像文件实例,可能好多人还不了解Hibernate映像文件,没有关系,看完本文你肯定有不少收获,希望本文能教会你更多东西。

Hibernate映像文件实例

们已经从改用这样的纯净的对象id中获取了不少好处。我们对equals()和hashCode()方法的实现更加简单而且容易阅读。这些方法再也不易出错而且无论在保存对象之前还是之后,它们都能和Collection一起正常工作。Hibernate也能够变的更快一些,这是因为在保存新的对象之前它再也不需要从数据库读取一个序列值。此外,新定义的equals()和hashCode()对于一个包含 id对象的对象来说是具有通用性的。这意味着我们可以把这些方法移动到一个抽象的父类当中去。我们不再需要为每一个域对象重新实现equals()和 hashCode(),而且我们也不再需要考虑对于一个类来说哪些字段的组合是唯一且不变的。我们只要简单地继承这个抽象类。当然,我们没必要强迫我们的域对象继承一个父类,所以我们定义了一个接口来保证设计的灵活性。

  1. public interface PersistentObject {   
  2. public String getId();  
  3. public void setId(String id);  
  4. public Integer getVersion();  
  5. public void setVersion(Integer version);  
  6. }  
  7. public abstract class AbstractPersistentObject implements PersistentObject {  
  8. private String id = IdGenerator.createId();   
  9. private Integer version;  
  10. public String getId() { return id;   
  11. }  
  12. public void setId(String id) { this.id = id; }  
  13. public Integer getVersion() { return version; }  
  14. public void setVersion(Integer version) { this.version = version; }  
  15. public boolean equals(Object o) {   
  16. if (this == o) return true;  
  17. if (o == null || !(o instanceof PersistentObject)) { return false; }  
  18. PersistentObject other = (PersistentObject)o;  
  19. // if the id is missing,   
  20. return false  
  21. if (id == null) return false;   
  22. // equivalence by id   
  23. return id.equals(other.getId());  
  24. }  
  25. public int hashCode() {   
  26. if (id != null) {  
  27. return id.hashCode();   
  28. } else {   
  29. return super.hashCode();   
  30. }  
  31. }  
  32. public String toString() {   
  33. return this.getClass().getName() + "[id=" + id + "]";  
  34. }  
  35. }  

现在我们有了一个简单而高效的方法来创建域对象。它们继承了AbstractPersistentObject,这个父类能在它们第一次被创建时自动赋予它们一个id并且恰当的实现了equals()和hashCode()这两个方法。域对象也得到了一个对toString()方法的合理的缺省实现,这个方法可以有选择地被重写。如果这是一个查询例子的测试对象或者例子对象,id值时可以被改变或者被设为null。否则它是不应当被改变的。如果因为某些原因我们需要创建一个继承自其它类的域对象,这个对象就应当实现PersistentObject接口而不是继承抽象类。

  1. public class Person extends AbstractPersistentObject {   
  2. // Person-specific fields and behavior here  

从上一个例子开始Hibernate映像文件就不会再改变了。我们不想麻烦Hibernate去了解抽象父类,相对的,我们只要保证每个持久化对象的映射文件包含一个id项(和一个被指派的生成器)和一个带有unsaved- value="null"属性的version标签。机敏的读者可能已经注意到,每当一个持久化对象被实例化的时候,它的id值得到了指派。这意味着当Hibernate在内存中创建一个已经保存过的对象时,虽然这个对象是已经存在并从数据库中读取的,它也会得到一个新的id。这不会产生问题,因为Hibernate会接着调用对象的setId()方法,用保存的真实id来替换新分配的id。剩下的id生成器并不是问题,因为实现它的算法是轻量级的(也就是说,它并不牵扯到数据库)。

到现在为止一切都很好,但是我们遗漏了一个重要的细节:如何实现IdGenerator.createId().我们可以为我们理想中的键值生成器(key-generation)算法定义一些标准。
◆键值可以不牵扯到数据库而很轻量级的产生
◆即使跨越不同的虚拟机和不同机器,键值也要保证唯一性。
◆如果可能键值可以由其它程序,编程语言和数据库生成,至少要能和它们兼容