读书人

仿照Warp Dynamic Finder的Hibernate

发布时间: 2012-10-30 16:13:36 作者: rapoo

模仿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 {@SaveLong save(Student student);@Deletevoid delete(Student student);@GetStudent 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 ref="sessionFactory" /></bean><bean id="studentService " />

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


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


非常的简单,也很初级,有什么不足,请大家多多指教,呵呵。public interface StudentDao { @Query( value = "count(case when aaa=:value then aaa end) from .....", sqlQuery = true ) public Integer count( @Parameter(name="value") String aaa);} 挺敏捷的class Student public String name; public String address;}@SqlFileList<Student> getStudent(Student student)StudentDao_getStudent.sqlselect * from student where name=/*student.name*/ and address =/*student.address*/ 挺敏捷的

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

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

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

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


挺敏捷的

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


这位仁兄说的很好!不过偶还是很喜欢去学习魔法的。实际项目中应用看来要找到志同道合者一起了, 庸者勿扰。

读书人网 >软件架构设计

热点推荐