在进行Hibernate开发过程中,我们通常会使用DAO模式,有一些通用的数据操作方法,如CRUD,我们通常会将这些方法集中在一个DAO,这样会简便很多。如在AppFuse中,创建了一个DAO接口,包含一些常用的方法,接口如下: 这里的代码包含了许多entity类型的信息,也就是DAO接口中的Class clazz。接下来AppFuse同样创建一个缺省的实现类:BaseDAOHibernate,将这个接口做一缺省实现。以后我们创建的新的DAO需要继承DAO接口,如UserDAO,RoleDAO都继承DAO接口,对应的DAO实现都继承BaseDAOHibernate,再实现指定的接口,如UserDAOHibernate继承BaseDAOHibernate,实现UserDAO接口。 如果你的项目在使用Java 5,那么再这么做可能有点不适合,在调用AppFuse的DAO接口时,你通常还需要进行额外的操作:造型(cast type),提供entity类名,List数据没有包含元素类型信息等,这里要感谢Java 5的Generics,让我们做同样的事情轻松多了,下面让我们看看在Java 5下如何规划DAO接口。首先我们创建同样的一个DAO接口,代码如下: 在这个接口中,我们提供了基本的CRUD和简单的查询(使用了Hibernate的Criterion),同时我们引入Generics机制,enity的类型我们用T代替,在后面就可以看到这样做的带来的好处,同时我们创建一个这个接口的缺省实现:bstractHibernateDao,代码如下: 在这个实现中,我们需要提供Entity的类型信息,也就是代码中的PoClass,AbstractHibernateDao只包含一个构造函数,那么所有继承该类的子类必须调用AbstractHibernateDao类的构造函数,保证了entity的类型被准确赋值。 下面让我们看看如何创建业务的DAO,我们只需创建一个新的DAO,继承AbstractDao即可,这里要提供entity的类型信息,如PersonPO,代码如下: 基本的CRUD完全没有了,我们只需关注其他的一些业务方面,在这个接口中只需继承AbstractDao<PersonPO>,其中PersernPO为entity的类型,这个是Generics需要的。下面我们看一下UserDao的接口实现,代码很简单,如下: 这里我们需要继承AbstractHibernateDao,同时提供entity的类型信息,同时创建一个默认的构造函数,然后调用AbstractHibernateDao的构造方法,进行entity类型赋值,这样UserDao的实现就完成了。 这里因为使用了Spring,接下来只需在Spring的配置文件中将UserDaoImpl进行声明定义即可。在你取得UserDao接口后,再调用的方式就完全以前不一样了,这里包含了entity的类型信息,而这以前都是Object类型,还需要了提供entity类的类型名称。下面的这两张图的对比相信你会看的一目了然。 |
使用Java 5 Generics特性定义的DAO |
AppFuse中定义的DAO(传统的DAO模式) 总结:通过引入Java 5的Generics,再回头设计一下DAO,你会发现有些事情处理起来方便很多,在以前,我们只能获取Object对象,现在我们完全可以获取指定类型的对象啦,操作和理解都方便啦。关于AbstractDao你可能有自己的想法,你可以根据具体情况更改一些,如添加Spring的Annotation Transaction,这样对事务控制也会简单很多;如将添加分页功能,关于分页,请参考本站关于分页的文章:分页,心中的痛?。 |