php entitydao,调查管理系统 -(4)DAO与Service层的泛型抽取与实现

1、设计 BaseDao 与 BaseDaoImpl

1)设计接口 BaseDao

每个实体都应有一个对应的Dao接口,封装了对这个实体的数据库操作。在每个Dao接口中都应有一个基本的增删改查的方法,但每个Dao接口中都写一遍就是重复的代码,可以把这些方法抽取到一个父接口中,定义为:

1 packagecom.atguigu.surveypark.dao;2 importjava.util.List;3 /**

4 * BaseDao接口5 */

6 public interface BaseDao{7 //写操作

8 public voidsaveEntity(T t);9 public voidsaveOrUpdateEntity(T t);10 public voidupdateEntity(T t);11 public voiddeleteEntity(T t);12 public voidbatchEntityByHQL(String hql,Object...objects); //按照HQL语句进行批量更新13 //执行原生的sql语句

14 public voidexecuteSQL(String sql,Object...objects);15

16 //读操作

17 publicT loadEntity(Integer id);18 publicT getEntity(Integer id);19 public ListfindEntityByHQL(String hql,Object...objects);20 //单值检索,确保查询结果有且只有一条记录

21 publicObject uniqueResult(String hql,Object...objects);22 //执行原生的sql查询(可以指定是否封装成实体)

23 publicList executeSQLQuery(Class clazz,String sql,Object...objects);24 }

2)设计实现类 BaseDaoImpl

每个Dao的接口还要有相应的实现类才可以,在每个DaoImpl中都要实现Dao接口中定义的所有方法,当然也包括公共的增删改查方法(BaseDao中定义的基本方法)。每个DaoImpl中都实现一遍公共方法显示是重复的,所以也可以抽取出来为一个父类BaseDaoImpl,在BaseDaoImpl中实现了BaseDao接口的所有方法,我们的DaoImpl只需要继承他就可以不用重复的写公共方法的实现了。

声明如下:

1 packagecom.atguigu.surveypark.dao.impl;2 importjava.lang.reflect.ParameterizedType;3 importjava.util.List;4 importjavax.annotation.Resource;5 importorg.hibernate.SessionFactory;6 importcom.atguigu.surveypark.dao.BaseDao;7 /**

8 * 抽象的dao实现,专门用于继承9 */

10 @SuppressWarnings("unchecked")11 public abstract class BaseDaoImpl implements BaseDao{12 @Resource13 private SessionFactory sessionFactory ; //让Spring注入sessionFactory

14 private Classclazz ;15 publicBaseDaoImpl(){16 //得到泛型化超类(返回值为参数化类型)

17 ParameterizedType type = (ParameterizedType) this.getClass().getGenericSuperclass();18 clazz = (Class) type.getActualTypeArguments()[0];19 }20

21 protected Session getSession() { //获取Session

22 returnsessionFactory.getCurrentSession();23 }24 //省略了对接口中方法的实现

25 }

这里用到了泛型技术,需要在程序执行过程中确定泛型T的具体类型clazz。获取clazz时有两种方法:★★★★

方法一:

Ⅰ、把clazz声明成protected修饰符的,这样子类中就可以访问了,

Ⅱ、在每个子类的构造方法中传递这个属性的值,如:

public RoleDaoImpl() { clazz = Role.class; }

public UserDaoImpl() { clazz = User.class; }

方法二:使用反射的方式(即上述BaseDaoImpl中使用的方法):

Ⅰ、在BaseDaoImpl的默认构造方法中写如下代码就可以了:

ParameterizedType pt = (ParameterizedType) this.getClass().getGenericSuperclass();

clazz = (Class) pt.getActualTypeArguments()[0];

Ⅱ、说明:即使BaseDaoImpl没有被定义为抽象类也不能直接使用,只能使用他的子类,否则这段代码就无效了。因为只能通过其子类指定了泛型的具体类型之后,才能够在BaseDaoImpl的构造方法中获取到clazz的具体类型。

2、设计 BaseService 与 BaseServiceImpl

1)设计接口BaseService

在设计BaseService时有个不成文的规定,就是将BaseDao中的基本方法全部都复制到BaseServic中即可,如有需要扩展的业务方法则再独立设计相应的Service接口,然后继承BaseService接口即可。

因此BaseService的定义如下:

1 packagecom.atguigu.surveypark.service;2 importjava.util.List;3 /**

4 * 基本的Service接口5 */

6 public interface BaseService{7 //写操作

8 public voidsaveEntity(T t);9 public voidsaveOrUpdateEntity(T t);10 public voidupdateEntity(T t);11 public voiddeleteEntity(T t);12 public voidbatchEntityByHQL(String hql,Object...objects);13 //执行原生的sql语句

14 public voidexecuteSQL(String sql,Object...objects);15

16 //读操作

17 publicT loadEntity(Integer id);18 publicT getEntity(Integer id);19 public ListfindEntityByHQL(String hql,Object...objects);20 //单值检索,确保查询结果有且只有一条记录

21 publicObject uniqueResult(String hql,Object...objects);22 //查询所有实体

23 public ListfindAllEntities();24 publicList executeSQLQuery(Class clazz,String sql,Object...objects);25 }

2)设计实现类 BaseServiceImp

在BaseServiceImpl中同样采用了泛型技术,方便程序的实现。在BaseServiceImpl中主要是通过Spring注入了dao,然后通过dao调用了BaseDaoImpl中的基本方法的实现,已完成基本的业务操作。

具体实现如下:

1 packagecom.atguigu.surveypark.service.impl;2 importjava.lang.reflect.ParameterizedType;3 importjava.util.List;4 importjavax.annotation.Resource;5 importcom.atguigu.surveypark.dao.BaseDao;6 importcom.atguigu.surveypark.service.BaseService;7 /**

8 * 抽象的Service实现,专门用于继承9 */

10 public abstract class BaseServiceImpl implements BaseService{11 private BaseDaodao ;12 private Classclazz ;13 @SuppressWarnings("unchecked")14 publicBaseServiceImpl() {15 ParameterizedType type = (ParameterizedType) this.getClass().getGenericSuperclass();16 clazz = (Class) type.getActualTypeArguments()[0];17 }18 @Resource //注入dao

19 public void setDao(BaseDaodao) {20 this.dao =dao;21 }22 //省略了对接口中方法的实现

23 }

注意:在这里注入的是BaseDao接口的实现类,并且[email protected],而是添加到set方法上,这样,在具体的Service实现类中可以覆写setDao方法,[email protected]ao实现类。如下所示:

1 //UserService接口

2 public interface UserService extends BaseService{}3 //UserServiceImpl实现类

4 @Service("userService")5 public class UserServiceImpl extends BaseServiceImpl implementsUserService {6 /**

7 * 重写该方法,目的是为了覆盖超类中该方法的注解,指明注入指定的Dao对象,否则spring8 * 无法确定注入哪个Dao---有多个满足条件的Dao.9 */

10 @Resource(name="userDao")11 public void setDao(BaseDaodao) {12 super.setDao(dao);13 }14 }

原文:http://www.cnblogs.com/KnightKitt/p/3951812.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值