`
Norther
  • 浏览: 25750 次
  • 性别: Icon_minigender_1
  • 来自: 上海
文章分类
社区版块
存档分类
最新评论

模仿Warp Dynamic Finder的Hibernate Dynamic Dao

阅读更多
看了Robbin前两天发的那帖,Warp framework - 一个相当有前途的Java轻量级Web开发框架(http://www.iteye.com/topic/168780),让人眼前一亮,特别是基于annotation的warp-dynamic-finder部分给人印象非常深刻,利用它,80%情况下Dao的实现不用去写了,只要定义个interface,加几个annotation轻松搞定,自己就着手实现了一个,基于spring的HibernateDaoSupport,其用法也很简单,如下:

public interface StudentDao {
	@Save
	Long save(Student student);

	@Delete
	void delete(Student student);

	@Get
	Student get(Long id);

	@Query("from Student as s where s.name = ? and s.age = ?")
	Student getByNameAndAge(String name, Integer age);//根据参数出现的次序绑定

	@Query("from Student as s where s.age > :age")
	List<Student> getStudentsAgeMoreThan(
			@Parameter("age") Integer age);//name绑定

	@Query("from Student as s where s.name like ?")
	Student getStudentNameLike(
			@Like(matchMode = MatchMode.START) String name);//支持like

	@Query(value = "delete Student where name = ?", executeUpdate = true)
	int deleteStudentByName(String name);//批量更新

	@Query("from Student as s order by s.id desc")
	@Conditions({ 
		@Condition("s.name = ?"), //动态条件添加,如果第一个参数不为null,该条件会被插入query string
		@Condition("s.age = ?") 
	})
	Student query(String name, Integer age);

}



这样一个Dao就定义OK了,非常容易,有两种使用方式,一种是利用AutoInjectDynamicDaoBeanPostProcessor,在spring中的bean初始化好之后,找到有InjectDao标注的方法就,利用动态代理生成StudentDao的代理实现并注入:

<bean class="com.norther.dynamic.dao.AutoInjectDynamicDaoBeanPostProcessor">
	<property name="sessionFactory" ref="sessionFactory" />
</bean>

<bean id="studentService " class="com.norther.dynamic.dao.test.StudentService" />


public class StudentService {

	private StudentDao studentDao;

	@InjectDao//会被注入StudentDao动态代理实现
	public void setStudentDao(StudentDao studentDao) {
		this.studentDao = studentDao;
	}


还有另一种方式是基于FactoryBean的DynamicDaoProxy,并自己指定要实现的Dao接口,如下:
<bean id="studentDao " class="com.norther.dynamic.dao.DynamicDaoProxy">
	<property name="dao" value="com.norther.dynamic.dao.test.StudentDao" />
</bean>
<bean id="teacherDao " class="com.norther.dynamic.dao.DynamicDaoProxy">
	<property name="dao" value="com.norther.dynamic.dao.test.TeacherDao" />
</bean>



非常的简单,也很初级,有什么不足,请大家多多指教,呵呵。
  • dynamicdao.zip (43.4 KB)
  • 描述: 依赖Spring,Hibernate,测试部分依赖EasyMock,SpringMock,HSQLDB,JUnit
  • 下载次数: 336
分享到:
评论
20 楼 spiritfrog 2008-03-25  
ygxdha 写道
ericxu131 写道
ygxdha 写道
seasar下面的一个子项目s2dao也是基于annotation的dao层实现,设计思想采用了ror约定大于配置的概念。初看起来很简单,不过在实际应用中,到了后期还是遇到了很多问题。我觉得一个企业开发中,最卡时间的不是这些类似与hello world的实现。而是对于复杂问题的可扩展性。

约定的确让很多事情变的简单,并且不用考虑太多东西 挺敏捷的


不过约定多了magic的东西也多了,对于开发成员能力普遍比较高的小团体,magic的东西不是问题。但是对于一些开发人员参差不齐,规模大但技术难度并不高,基础编码人员有一定流动性的项目。约定太多会给项目带来进入难度加大,新人的培训代价过高的缺点。 之前robin关于ror为什么不能大规模进入企业的评价深入我心。我想这种约定大于配置,魔法元素过多的框架设计思想,最好用处的确是用来体现绝顶高手的强,让人们看到企业开发如果做到一定的极致能达到如斯效率。并不一定能适合其它的大范围开发。


这位仁兄说的很好!不过偶还是很喜欢去学习魔法的。实际项目中应用看来要找到志同道合者一起了, 庸者勿扰。
19 楼 indexchen 2008-03-24  
Norther 写道
再次更新,加入动态条件插入,支持like,详见一楼,谢谢。

要说DAO,grails的实现比warp简单多了
18 楼 Norther 2008-03-22  
再次更新,加入动态条件插入,支持like,详见一楼,呵呵。
17 楼 jdk 2008-03-21  
路过,今天就不发表意见了,做点别的贡献吧。。。
介绍个MSN 群:china.java@live.com
中国JAVA协会,加为好友即可。
里面都是专业java的,现在已经100多人了,
在线交流的很多。
16 楼 Norther 2008-03-21  
代价为什么大?大在哪了?我实在不明白。。。

另外,hibernate2年前就提供了批量删除和更新的API

详见query.executeUpdate();
15 楼 ygxdha 2008-03-21  
Norther 写道
谢谢你的建议,一个框架没有试图做所有事,就是提供可扩展的空间,一种特殊的螺丝,你的螺丝刀搞不定,那拿来能搞定的螺丝刀搞好了,so easy,复杂的查询逻辑,你可以自己实现,继承HibernateDaoSupport或者随便怎么样,大部分简单的用DynamicDao,它只是对拿些API进行了封装,这样不会有任何问题的。

另外,复杂的HQL放在代码里就是很臃肿,hibernate提供了分离HQL到外部的功能,named query,在DynamicDao只需要这样

     @Query(name="queryByXXXX")//
     public Student queryByXXXX(.....)
     //这里封装了,session.getNamedQuery(String queryName),会将该名称对应的hql从配置文件里读出来创建query对象



一种特殊的螺丝,你的螺丝刀搞不定,那拿来能搞定的螺丝刀搞好了,so easy
我想这个点是我们俩意见不一样的地方。
我是觉得螺丝刀应该提供可扩展的接口,好比那种多功能的螺丝刀,换个螺丝头都可以搞其它的螺丝。如果因为特殊螺丝就需要使用特定的螺丝刀,代价大了点。

hibernate 最开始对于批量的删除没有好的解决方法,还是要依赖于jdbc,这样的东西偶实在不喜欢。不知道现在的hibernate发展到什么地步,是否可以不另外使用jdbc没。


14 楼 Norther 2008-03-21  
谢谢你的建议,一个框架没有试图做所有事,就是提供可扩展的空间,一种特殊的螺丝,你的螺丝刀搞不定,那拿来能搞定的螺丝刀搞好了,so easy,复杂的查询逻辑,你可以自己实现,继承HibernateDaoSupport或者随便怎么样,大部分简单的用DynamicDao,它只是对hibernate那些API进行了封装,这样不会有任何问题的。

另外,复杂的HQL放在代码里就是很臃肿,hibernate提供了分离HQL到外部的功能,named query,在DynamicDao只需要这样

     @Query(name = "queryByXXXX")//
     public Student queryByXXXX(.....)
     //这里封装了,session.getNamedQuery(String queryName),会将该名称对应的hql从配置文件里读出来创建query对象

13 楼 ygxdha 2008-03-21  
ericxu131 写道
ygxdha 写道
seasar下面的一个子项目s2dao也是基于annotation的dao层实现,设计思想采用了ror约定大于配置的概念。初看起来很简单,不过在实际应用中,到了后期还是遇到了很多问题。我觉得一个企业开发中,最卡时间的不是这些类似与hello world的实现。而是对于复杂问题的可扩展性。

约定的确让很多事情变的简单,并且不用考虑太多东西 挺敏捷的


不过约定多了magic的东西也多了,对于开发成员能力普遍比较高的小团体,magic的东西不是问题。但是对于一些开发人员参差不齐,规模大但技术难度并不高,基础编码人员有一定流动性的项目。约定太多会给项目带来进入难度加大,新人的培训代价过高的缺点。 之前robin关于ror为什么不能大规模进入企业的评价深入我心。我想这种约定大于配置,魔法元素过多的框架设计思想,最好用处的确是用来体现绝顶高手的强,让人们看到企业开发如果做到一定的极致能达到如斯效率。并不一定能适合其它的大范围开发。

12 楼 ygxdha 2008-03-21  
Norther 写道
ygxdha 写道
seasar下面的一个子项目s2dao也是基于annotation的dao层实现,设计思想采用了ror约定大于配置的概念。初看起来很简单,不过在实际应用中,到了后期还是遇到了很多问题。我觉得一个企业开发中,最卡时间的不是这些类似与hello world的实现。而是对于复杂问题的可扩展性。


一个人说他的磁性螺丝刀很有用,可以将螺丝吸附在螺丝刀头上,会比一般的螺丝刀方便一些。

另一个人说螺丝刀不是盖房子的全部,盖房子时最卡时间的不是小小的螺丝刀,而是....

我不明白你的话是什么意思,这个东西本来就是个DEMO性质的,企业应用不只是DAO,一个DAO工具不可能解决的企业应用

中100%的问题,没有人有说这个DAO工具的出现可以将企业应用中最卡时间的问题解决,谢谢。


sorry,可能是我开始表意不是很清楚。

我觉得关于螺丝刀的使用场景应该是这样的。
盖房子的设计师给下面的施工人员提供了螺丝刀A,该螺丝刀非常的方便好用,修房子的过程中基本90%的螺丝都可以轻松搞定,不过需要一定的使用技巧。但是突然有一天,遇到了一种比较特别的螺丝,该螺丝刀不提供支持,施工人员找设计师,请求解决方法。设计师告诉他们,不好意思,对于特殊螺丝的处理,该螺丝刀并不能通过添加新的功能来支持,让我考虑考虑,再给你们找一套新的螺丝刀用来对该特殊螺丝的支持,并且在此之前,对于新的螺丝刀,需要对你们还进行一些使用培训。
my god。如果你是施工人员,这个时候难道不会抓狂?

我是觉得这样的DAO框架在本身简单易行的同时,需要提供足够的可扩展性,对于一些比较复杂的特殊需求,能够方便的扩展。只有这样在开发的后期才不会因为一些比较特殊的问题而搞的头破血流。

S2Dao提供的最基础的功能和仁兄的基本一样,S2Dao还提供一些更加强大的功能,不过到了后期,为了一些特殊需求,我要频繁的进入S2Dao的源代码进行修改。这种频繁修改开源项目代码的事虽然干起来过瘾,但并不是一个项目所乐意见到的,技术风险太大了。

DAO层本身是不能解决100%的企业问题,但是它是一个层,和数据库的交互都依赖于它。我不喜欢在使用某个dao工具的同时还去使用另外一种dao工具。这些是高手做的事,并不适合一些普通项目中的一些普通员工。如果一个项目的dao层中ibatis,hibernate,jdbc同时存在,很可怕,很可怕。


关于这种annotation dao的设计,仁兄可以参考下S2dao的。我把我所知道的列下来,如果能对你的设计有一点点的帮助。

1:关于很长的sql。这样的sql如果用annotation直接放在代码里面,简单的dao的interface会看起来非常的臃肿。
可以考虑添加函数级别的annotation  @sqlfile. 该annotation让该函数和某个特定的sql文件绑定起来。
2:结构类型参数的支持。 寻址方式采用ognl。
class Student
   public String name;
   public String address;

}

@SqlFile
List<Student> getStudent(Student student)

StudentDao_getStudent.sql

select * from student where name=/*student.name*/ and address =/*student.address*/

11 楼 ericxu131 2008-03-19  
ygxdha 写道
seasar下面的一个子项目s2dao也是基于annotation的dao层实现,设计思想采用了ror约定大于配置的概念。初看起来很简单,不过在实际应用中,到了后期还是遇到了很多问题。我觉得一个企业开发中,最卡时间的不是这些类似与hello world的实现。而是对于复杂问题的可扩展性。

约定的确让很多事情变的简单,并且不用考虑太多东西 挺敏捷的
10 楼 Norther 2008-03-19  
ygxdha 写道
seasar下面的一个子项目s2dao也是基于annotation的dao层实现,设计思想采用了ror约定大于配置的概念。初看起来很简单,不过在实际应用中,到了后期还是遇到了很多问题。我觉得一个企业开发中,最卡时间的不是这些类似与hello world的实现。而是对于复杂问题的可扩展性。


一个人说他的磁性螺丝刀很有用,可以将螺丝吸附在螺丝刀头上,会比一般的螺丝刀方便一些。

另一个人说螺丝刀不是盖房子的全部,盖房子时最卡时间的不是小小的螺丝刀,而是....

我不明白你的话是什么意思,这个东西本来就是个DEMO性质的,企业应用不只是DAO,一个DAO工具不可能解决的企业应用

中100%的问题,没有人有说这个DAO工具的出现可以将企业应用中最卡时间的问题解决,谢谢。
9 楼 ygxdha 2008-03-19  
seasar下面的一个子项目s2dao也是基于annotation的dao层实现,设计思想采用了ror约定大于配置的概念。初看起来很简单,不过在实际应用中,到了后期还是遇到了很多问题。我觉得一个企业开发中,最卡时间的不是这些类似与hello world的实现。而是对于复杂问题的可扩展性。
8 楼 strongkill 2008-03-18  
不知道为什么.本人非常不喜欢使用过多的xml配置.
7 楼 Norther 2008-03-17  
qilei 写道
能不能提供demo的相关jar文件,谢谢!

hibernate,hibernate-annotation,ejb3-persistent这几个在hibernate官方网站都能找到,

hsqldb在http://hsqldb.org/可以下载,是一个轻量的数据库

剩下的google随便一搜索就有了 : )
6 楼 qilei 2008-03-17  
能不能提供demo的相关jar文件,谢谢!
5 楼 williamy 2008-03-17  
DAO可以认为是一种模式
模式一般是大家都认可的一种编程方式,习惯,经验的总结
模式的应用往往是运行效率的降低,但是可维护性提高了不少
大家都理解同一种模式的时候,你跟别人交流,也就只需要说一下模式的名字,而不需要特地解释。
当你使用DAO的时候就是希望,你只告诉别人说“我这里使用了DAO”就不再需要告诉别人怎么实现,因为对方理解DAO,

我现在就说这些,另外我想说,等东部老大来消灭你,看你22:0得意的样
4 楼 wangxin0072000 2008-03-17  
现在的技术发展真快,多亏有这么多懒人。编码越来越省事了。
3 楼 robbin 2008-03-16  
看过源代码了,annotation的确用的很不错
2 楼 Norther 2008-03-16  
剑 事 写道
count(case when aaa='555' then aaa end) from .....

这样的什么方法处理


dynamic dao只是对hibernate进行封装,这个当然可以做到,例如

public interface StudentDao {
     
     @Query(
         value = "count(case when aaa=:value then aaa end) from .....",
         sqlQuery = true
         )
     public Integer count(
           @Parameter(name="value") String aaa);


}
1 楼 剑事 2008-03-16  
count(case when aaa='555' then aaa end) from .....

这样的什么方法处理

相关推荐

Global site tag (gtag.js) - Google Analytics