DAO层是否还有必要?

小弟今天初次发帖,还望各位大虾不吝赐教!
这几天一直在思考一个问题:就是DAO层是还需要?大家都知道传统的DAO就是对一个对象的增删查改,然而我觉得这些工作完全可以放在这个对象去做,如在这个对象中的除了我们常见的一些属性和setter和getter方法,还可以增加save,find,update,delete方法来完成DAO操作,我结合spring+hibernate做了个简单的save的操作,觉得这完全是可行的。

//所有要保存对象的基类
public class BaseModel extends HibernateDaoSupport{
public String id;//对应中的ID
//定义对象的保存操作
public void save(){
getHibernateTemplate().save(this);
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
}

//具体的要保存的对象
public class Model1 extends BaseModel implements Cloneable {
private String name;
//无参构造函数
public Model1() {
}
//全参构造函数
public Model1(String anName) {
this.name = anName==null?anName:anName.trim();
}

/**
* 静态构造方法
*/
public static Model1 getInstance() throws Exception {
try{

Model1 model = (Model1)new XmlBeanFactory(
new ClassPathResource("xx/xx/xx/applicationContext.xml")).getBeanFactory().getBean("model1Proxy");
return model;
}catch(Exception e) {
e.printStackTrace();
}
}
}

//hibernate配置
<hibernate-mapping package="xxx.xxx.xxx.Model1">
<class name="model1" table="TableName">
<id name="id" type="string">
<column name="T_ID" length="128" />
<generator class="uuid.hex" />
</id>
<property name="name" type="string">
<column name="T_NAME" length="128" />
</property>
</class>
</hibernate-mapping>

//spring配置
<beans>
<bean id="_sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean" singleton="true">
<property name="configLocation">
<value>xx/xx/xx/xx/hibernate.cfg.xml</value>
</property>
</bean>

<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory">
<ref local="_sessionFactory" />
</property>
</bean>
<bean id="model1" class="xxx.xxx.xxx.xxx.Model1">
<property name="sessionFactory">
<ref local="_sessionFactory"></ref>
</property>
</bean>
<bean id="model1Proxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager">
<ref bean="transactionManager" />
</property>
<property name="target">
<ref local="model1" />
</property>
<property name="proxyTargetClass">//强制Spring采用CGLIB进行代理
<value>true</value>
</property>
<property name="transactionAttributes">
<props>
<prop key="save*">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>
</beans>
//test
Model1 testModel = (Model1)Model1.getInstance();
Model1.setName("test");
testModel.save();//保存数据

通过我的测试这个save方法是成功的,那我就想如果把所有的增删查改放到对象中应该是完成可行的,这样做的就可以避免了DAO层的编写,而对于DAO层解耦的作用,这里也可以通过不同的BaseModel来实现,可以抽象出一个接口,包括save,find,update,delete方法,通过不同的实现来达到解耦目的!

对于这个想法还处于萌芽状态,希望得到各位的指点,是否具有可行性?


自己先顶,鼓励下!^_^

Evans DDD中有Repository就可以替代DAO,主要取决于对DAO的理解,两者也是可以并存的,可参考本站这两个标签下的讨论

可能对象会用于各层之间的数据传输只用
这样的话 算不算DAO渗透到其他层去了?
在使用对象时需要由spring管理,还要加载HibernateDaoSupport,还是暂时持观望态度

说一下拙见:

使用仓库处理数据的存储,这个存储可以包括DB,内存,文件等等。而Dao,认为可以把它作为ORMapping的一层,等到数据库慢慢弱化(我说的是E-R弱化)后,可以慢慢减少Dao的能力。

首先,我认为这一层是可以省略的,如banq老师说的可以用repository替代,其实这就是个持久层,但总会被用得很广;
其次,我不完成认同楼主的观点,放到你所谓的对象中,这个可能会违反对象的单一责任原则,还有就如上面的兄弟说的,如果这个对象贯穿所有层,那就会把这些方法渗透到其他层去!

首先谢谢大家的回复,每个的回复都是对我的帮助!
》》在使用对象时需要由Spring管理
个人觉得对象由spring管理应该是没有什么问题的,spring本来就是一个大的工厂
[该贴被pliaozrlp于2009-01-06 22:29修改过]

>Evans DDD中有Repository就可以替代DAO,主要取决于对DAO的理解,两者也是可以并存的,可参考本站这两个标签下的讨论

曾经看你对仓储的定义是:Repository是对象的仓库,也就是保存对象的地方,这个仓库就是我们普通意义的仓库.Repository=对象工厂+对象缓存+DAO

那我可不可理解为spring就是一个仓储呢,本来spring最初的功能就是管理所有的类以及类之间的关联关系。

回到本文的内容,那就是说仓储就是对子DAO的进一步的封装?

>>个人觉得对象由Spring管理应该是没有什么问题的,spring本来就是一个大的工厂
我考虑是说dao层原本在与数据库交互时才由spring产生,但你可能会在控制层,或者其他地方就产生,对象可能过多的产生,对整个程序的效率会不会有影响呢?应该说还是会有一些的吧。

>>我考虑是说dao层原本在与数据库交互时才由Spring产生,但你可能会在控制层,或者其他地方就产生,对象可能过多的产生,对整个程序的效率会不会有影响呢?应该说还是会有一些的吧。

可是这些要保存的对象本来就是要产生的呀,对于一次保存操作都需要有个对象,如PO。以前我们的操作是要保存的时候就是new一个对象,然后设置它的属性值,再就是调用持久层的操作来进行保存.

同时我还是很赞同freeren的观点的,DAO层就是持久层。那既然我们已经有了像Hibernate之类的持久层框架是不是就可以省略这个DAO了呢?

Repository不是DAO,它要求你以DDD思维思考.
而DAO纯粹是针对数据库访问.

大家可以参考jivejdon源码。

提个问题,如果用对象查找的话,还是比较麻烦的,单表操作还挺好用,但是有些查询统计功能,要5,6张表连查,意味着涉及到5,6个对象嵌套在一起才能生成一个sql,这个就不如用面向数据库思维的DAO,任何表的组合的查询都返回一个HashMap方便。

如果向楼上说的专门需要面向数据表的搜索,且需要很高的效率,可能还是将返回结果转换为对象使用比较好。

没有可以无限使用的规则,OO也是有使用范围的。不要期望一张药方可以包治百病,总是要适实选择和创造方法。

我同意楼上IceQi关于没有一张药方可以包治百病的观点.
但是
考虑到现实问题,需求总要制定成方案阿
用最简单得学生\选课\成绩作为例子
可能这个系统大多数模块的操作都建立在学生表\课程表\成绩表的单表操作上,用Object-Repository能很好地完成工作,但是最后有一个模块是综合查询,要求能够通过学生查成绩,课程;通过课程查学生,成绩,比如"数学或者语文得分在50~80之间的男生列表"总之是任意组合的查询.仿佛这样的查询用Dao和手拼sql容易一些.
那么作为架构设计的你会怎么拿方案?
仅为了最后一个功能用Dao+sql,还是为了大多数功能Object+Repository??或者其多数能用Object+Repository只有最后一个功能Dao+sql(两种持久化同时存在)
考虑现在系统的功能多样化很少会有专门一个系统只面向数据搜索或者只面向于一般查询...

数据和对象总是在一个点上进行转化的,Hibernate构造了一个点,xxxORM构造了一个点,我们的业务过程也可以构造出这样的一个点。

不要用一种固定的思想去思考所有的问题,所有的事物都是在变化中的。对于ORM其实我们始终都需要思考在“我们特定的业务过程中”应该将哪一个点上将数据和对象进行转换,只是通常的情况下Hibernate已经代替我们完成了,所以我们也就不需要再思考了,但是这并不代表一种最好的实践方式。

如你所设的情况下我们必须要返回来重新思考转换的问题了。对象会包含一些数据,如何将总体上的数据划分入各个不同的对象中以更加符合一个特定业务过程的描述,这就需要根据每一个特定的场景进行划分了。在数据表和对象间总还是有一些沟壑,甚至于产生了不同的思考方式,所以在我们进行数据到对象间的划分时可能需要进行一种转换,不能够简单的将一张表的结构映射为一个对象,一张表里面的数据可能分布在不同的对象中,同一个对象中的数据也可能来自于不同的数据表甚至于不同的数据库。这样的划分方式就要依赖于个人对对象和业务过程的理解了。

另外OO是方式不是目的,我们选择OO是因为更多的情况下他能为我们找到一种最佳的实践方式,但是不排除在某些特定的情况下(人员、业务过程====各种原因)一个OO的方式可能比较于一个面向过程的方式更加的得不偿失,此时可以大胆的进行抛弃。只选对的,不选贵的。当然这一段是题外话了。