翻了翻老帖子,看到Robbin当年下站贴说实现同样需求对比Java代码和RoR代码(http://www.iteye.com/topic/57075?page=1),我始终搞不明白为什么说ActiveRecord是充血模型,而将DAO和Domain分开就不是了,对于我的那个封装JDBC(见原帖),我又把Hibernate和Spring加进来,进一步模仿了一下RoR,先看测试:
public void testEmployeeExtendsBase(){
//按ID查询
Employee e=new Employee();
e=(Employee) e.findById(43442l);
System.out.println(e.getFullName());
//查询
Employee e2=new Employee();
e2.setFullName("张三");
String effectiveDateProperty = "effectiveDate";
Date lo = getSwitchDate("2005-01-03");
Date hi = getSwitchDate("2010-09-02");
Criterion effectiveDateRange = Restrictions.between(
effectiveDateProperty, lo, hi);
/* 仿效RoR代码:
def processing_tasks
find :all, :conditions => ["start_time <= ? AND end_time is null", Time.now]
end */
List<Employee> employees=(List<Employee>)e2.find_All(effectiveDateRange);
for(Employee emp:employees){
System.out.println("员工编号:"+emp.getId()+"|| 员工姓名:"+emp.getFullName());
}
}
再看Employee代码
@Entity
@Table(name = "Employee")
public class Employee extends Base{
@Id
private Long id;
private String fullName;
private Date effectiveDate;
private Department department;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getFullName() {
return fullName;
}
public void setFullName(String fullName) {
this.fullName = fullName;
}
public Date getEffectiveDate() {
return effectiveDate;
}
public void setEffectiveDate(Date effectiveDate) {
this.effectiveDate = effectiveDate;
}
public Department getDepartment() {
return department;
}
public void setDepartment(Department department) {
this.department = department;
}
}
我和firebody的实现不太一样(http://www.iteye.com/topic/65406),Base继承了泛型DAO,并且动态注入子类,和SessionFactory,而SessionFactory由Spring初始化。
我的find_all是个多态方法,可以放入Criterion... criterion,HQL,并且内部基于一个QBE+QBC的查询,并且这个QBE是经过扩展的,它支持关联关系。
如果POJO或者实体类可以强制继承某个基类了,如本文的Base,我们又回到了EJB时代,独立测试的领域模型不见了。
从来都没有人说过一定要一个Service配一个DAO,一个DAO配一个Entity,这完全取决于你的需要,然后采取的不同模式!