关于服务,Daos和介于两者之间 - 初学者的困境

时间:2013-05-16 07:21:36

标签: java spring hibernate service dao

我是分层架构的新手,+ spring + hibernate 在阅读了关于类层次结构应该如何的一些指南之后 -

我想出了这个结构:

public interface GenericDAO {

   public <T> T getItemById(long id, Class<T> c);

   public <T> int save(T... objectsToSave);

   public <T> int saveOrUpdate(T... objectsToSave);

   public <T> int delete(T... objectsToDelete);
       .
       .
}

现在我所有其他daos impls都使用这个泛型dao作为私有字段,以便使用它的基本方法: 即:

@Repository
public class UserDAOImpl implements UserDao {

      @Autowired
      private GenericDAO dao;

      @Override
      public int deleteUser(User u) {
        return dao.delete(u);

      }

      .
      .
      .
}

我的服务是这样的:

 @Service
 public class UserServiceImpl implements UserService {

     @Autowired
     private UserDao userDao;


     @Transactional(readOnly = false)
     public int deleteUser(User u) {
         return userDao.deleteUser(u);
     }
         .
         .
         .
 }

我不知道为什么我需要在我的项目中使用UserDaoImpl,CarDaoImpl,XDaoImpl?它看起来真的很多余,因为所有的XDaoImpls看起来都是一样的:

 @Repository
 public class UserDAOImpl implements UserDao {

      @Autowired
      private GenericDAO dao;

      @Override
      public int deleteUser(User u) {
        return dao.delete(u);

      }

      .
      .
      .
}

@Repository
public class CarDAOImpl implements CarDao {

      @Autowired
      private GenericDAO dao;

      @Override
      public int deleteCar(Car c) {
        return dao.delete(c);

      }

      .
      .
      .
}

@Repository
public class XDAOImpl implements XDao {

      @Autowired
      private GenericDAO dao;

      @Override
      public int deleteX(X c) {
        return dao.delete(c);

      }

      .
      .
      .
}

我可能不会创建任何XDaoImpl而只是使用GenericDaoImpl来保存很多类创建,不是吗?

如果生病需要任何复杂的动作,比如deleteUserCar(User u),我可以在服务中实现逻辑:

UserService {
          public void deleteUserCar(User u) {
             Car c = u.getCar();
             CarService cs.deleteCar(c);

          }  
}

我错过了什么吗? 任何人都可以提供一个例子,只使用GenericDaoImpl代替XDaoImpl会让我后悔吗?

感谢

2 个答案:

答案 0 :(得分:1)

  • 您的服务稍后将调用businesslogic,而不是仅仅将方法传递给DAO。它可以验证值(例如它是否存在并且应该是唯一的),运行计算(例如int getStock() { return bought - sold; }等等。

  • 通用DAO很棒,但考虑abstract class而不是interface。这样您就不需要创建多个create(),只需扩展抽象DAO(例如CarDAO extends AbstractDAO<Car>)。

  • 您的扩展DAO会将class句柄传递给通用抽象DAO(如上例所示)。

  • 您的扩展DAO稍后将实现仅适用于该特定对象的额外方法,例如:List<Car> getCarsWithColor(Color color)

  • 您的服务 - &gt; DAO关系并不总是一对一的。考虑这些DAO:TruckDAOCarDAOVanDAO包含对象Truck extends VehicleCar extends VehicleVan extends Vehicle。您需要三项服务,还是VehicleService覆盖它(您可能会为所有Vehicle运行逻辑吗?

  • 重新考虑界面的使用,this问题适用于C#,但概念是相同的。

答案 1 :(得分:0)

我的建议是:保持简单!请不要创建过多的抽象导致过多的复杂性,请记住,如果你创建了很多你不需要的代码,那么你将不得不使用那些代码:你甚至不知道的大量垃圾它的目的是什么,大量的代码模糊了你的应用程序的真正目标。

所以在这个特殊情况下,我建议:

  1. 忘记创建DAO接口:它们旨在抽象DAO实现,以便从数据库(例如MySQL到SQLServer)“轻松”切换,但是想想!:这是一件非常罕见的事情:它更多切换系统比切换数据库更常见

  2. 将GenericDao放入垃圾桶(世界不是关于CRUD,请转到您的利益相关者并询问他们真正需要什么)

  3. 使用简单的DAO Layer和Service Layer,你可以用Spring实现它:我想象 您可以在DAO层中使用SimpleJDBCTemplate并在服务层中调用DAO方法

  4. 为什么要使用Spring呢?你问过自己它的目的是什么?目前我以这种方式使用MyBatis:我创建了由POJO服务调用的Mappers(类似于DAO的东西)。简单,实用和直接,没有Spring,普通的旧Java,就像冠军一样。