14

我一直在阅读一些教程,我可以看到大多数 MVC 实现

基于:

1)一个dao接口,例如“IUserDao”

2)该接口的一个dao impl - “mySimpleUserDaoImpl”

3) 持久化服务接口:“IUserService”

4) 和一个 impl - “UserServiceImpl”

这是最佳做法吗?我的意思是我问这个问题的原因是因为有 30 个服务与 getXById()、deleteX(x)、createX(x) 方法或多或少相同,这似乎是多余的。

请考虑到我使用的是 spring 3 和 hibernate 4,我决定在开始用代码敲击键盘之前先问这个问题

谢谢。

4

4 回答 4

10

如果您刚刚开始开发,请查看Spring JPA。服务应该是一对多存储库 (DAO)。但我也不会再手动创建所有样板代码。Spring JPA 消除了基本的 CRUD 和搜索功能以及分页。

这是一个视频,介绍了 Spring、JPA、Hibernate 的所有配置,并以 Spring Data JPA 结束,向您展示了所有被消除的样板代码。

要使用 Spring Data JPA,您的存储库接口最终是:

package com.mysampleapp.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import com.wcfgroup.model.Employee;

@Repository("employeeRepository")
public interface EmployeeRepository extends JpaRepository<Employee, Long> {
    Employee findBySsn(String ssn);
}

然后是使用 Spring Data JPA 的 XML 配置:

<jpa:repositories base-package="com.mysampleapp.repository"/>

现在为您处理所有样板代码。您不再需要创建具有查找方法和基本 CRUD 功能的基本存储库类。该JpaRepository接口提供了许多不错的功能,您无需为实现做任何事情。

于 2013-05-14T16:55:02.017 回答
4

每个模型都必须有 dao、daoImpl、service、serviceImpl。

  • 用户道
  • UserDaoImpl
  • 用户服务
  • 用户服务实现

您可以使用通用类 EntityDaoImpl 和接口 EntityDao,如下所示:

实体道:

public interface EntityDao<E> {

void persist(E e) throws Exception;

void remove(Object id) throws Exception;

E findById(Object id) throws Exception;
}

EntityDaoImpl:

public class EntityDaoImpl<E>  implements EntityDao<E> {

@PersistenceContext(unitName="UnitPersistenceName")
protected EntityManager entityManager;

protected E instance;
private Class<E> entityClass;

@Transactional
public void persist(E e) throws HibernateException{     
    getEntityManager().persist(e);
}
    @Transactional
public void remove(Object id) throws Exception{     
    getEntityManager().remove((E)getEntityManager().find(getEntityClass(), id));
}

public E findById(Object id) throws Exception {     
    return (E)getEntityManager().find(getEntityClass(), id);    
}
    public EntityManager getEntityManager() {
    return entityManager;
}
public void setEntityManager(EntityManager entityManager) throws Exception{
    this.entityManager = entityManager;
}

    public Class<E> getEntityClass() throws Exception{      
   if (entityClass == null) {
            Type type = getClass().getGenericSuperclass();
          if (type instanceof  ParameterizedType) 
          {
              ParameterizedType paramType = (ParameterizedType) type;
              if (paramType.getActualTypeArguments().length == 2) {
                    if (paramType.getActualTypeArguments()[1] instanceof  TypeVariable) {
                       throw new IllegalArgumentException(
                          "Can't find class using reflection");
                   }
                    else {
                       entityClass = (Class<E>) paramType.getActualTypeArguments()[1];
                  }
               } else {
                  entityClass = (Class<E>) paramType.getActualTypeArguments()[0];
                }
           } else {
              throw new Exception("Can't find class using reflection");
          }
        }
       return entityClass;
   }
}

你可以这样使用:

public interface UserDao extends EntityDao<User> {

}

public class UserDaoImpl extends EntityDaoImpl<User> implements UserDao{

}
于 2013-05-14T17:29:34.603 回答
1

为每个模型创建一个单独的服务是一种方法,我见过现实世界的应用程序这样做,但我不推荐这样做。这对于简单的 CRUD 案例来说是多余的,对于更复杂的案例(您实际上希望事务跨越多个 DAO 调用)没有帮助。它给你留下了很多无用的代码。可以使用 Spring Data 指定 DAO,服务将是样板文件,每个方法都包装对 DAO 的调用。Spring 应该有助于减少样板文件,而不是强制它。

如果您有一个完全 CRUD 应用程序,那么您可以合法地不使用服务,将 @Transactional 放在 DAO 上,并从控制器调用 DAO。如果服务没有发挥作用,那就摆脱它。

如果您在应用程序中确实有实际的业务逻辑,那么当用户调用可能涉及调用不同 DAO 的某些内容时,这些调用通常应该发生在同一个事务中,这样如果某件事失败,一切都会回滚。(此外,创建事务相对昂贵,如果您有一个控制器为不同的实体调用不同的服务,那么这将很慢。)这就是服务派上用场的地方,服务指定用户想要的低级用例执行并允许指定事务行为。

对于 CRUD 案例,我更喜欢使用 Grails 或 Play 或 Rails 之类的工具,而不是使用 Spring MVC 编写 Java。例如,Grails 将为您生成视图和控制器,通过 GORM 提供基本的数据访问(因此无需编写 DAO),并且它可以让您在发现需要它们的情况下轻松指定服务。

于 2013-05-16T13:17:09.207 回答
1

不,没有必要有 30 个服务层或 30 个 dao 层。您应该指定不考虑实体明智但业务功能明智的层。可以有 5 或 6 个与某些功能相关的实体,这些实体应该在一层。但是,如果需要,您仍然必须在这些冗余层中使用 getXById()、deleteX(x)、createX(x)。

于 2013-05-14T16:23:21.547 回答