java Hibernate 和 Spring - Dao,Services

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16547862/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 23:16:40  来源:igfitidea点击:

Hibernate and Spring - Dao ,Services

javaspringhibernateservicedao

提问by Urbanleg

I've been reading some tutorials and I could see that most of the MVC implementations

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

are based on:

基于:

1) a dao interface for example "IUserDao"

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

2) a dao impl of that interface - "mySimpleUserDaoImpl"

2) 该接口的 dao 实现 - “mySimpleUserDaoImpl”

3) a service interface for persistance : "IUserService"

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

4) and a impl - "UserServiceImpl"

4) 和一个 impl - "UserServiceImpl"

is this the best practice? i mean the reason i ask this question is because it seem redundant to have 30 services with getXById(), deleteX(x), createX(x) methods that are doing more or less the same.

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

please take into account that I'm using spring 3 and hibernate 4, and I decided i will ask this question before i start slamming my keyboard with code

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

thanks.

谢谢。

采纳答案by bh5k

If you are just starting development, look into Spring JPA. A service should be One-to-Many Repositories (DAO). But I would also not create all of that boilerplate code by hand anymore. Spring JPA eliminates the basic CRUD and search functions as well as pagination.

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

Here is a videothat walks through all of the configuration for Spring, JPA, Hibernate, and finishes up with Spring Data JPA showing you all of the boilerplate code that is eliminated.

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

To use Spring Data JPA, your repository interface ends up being:

要使用 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);
}

And then the XML configuration to use Spring Data JPA:

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

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

All of the boilerplate code is now handled for you. You no longer need to create a basic repository class with find methods and basic CRUD functions. The JpaRepositoryinterface offers a lot of nice features and you don't have do anything for the implementation.

现在已为您处理所有样板代码。您不再需要使用 find 方法和基本 CRUD 函数创建基本存储库类。该JpaRepository界面提供了许多不错的功能,您无需为实现做任何事情。

回答by 3d5oN

It′s necessary have dao, daoImpl, service, serviceImpl for each model.

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

  • UserDao
  • UserDaoImpl
  • UserService
  • UserServiceImpl
  • 用户道
  • 用户道Impl
  • 用户服务
  • 用户服务实现

You can use a generic class EntityDaoImpl anf the inteface EntityDao, like this:

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

EntityDao:

实体道:

public interface EntityDao<E> {

void persist(E e) throws Exception;

void remove(Object id) throws Exception;

E findById(Object id) throws Exception;
}

EntityDaoImpl:

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;
   }
}

And you can use like this:

你可以这样使用:

public interface UserDao extends EntityDao<User> {

}

and

public class UserDaoImpl extends EntityDaoImpl<User> implements UserDao{

}

回答by Nathan Hughes

Creating a separate service for each model is one way to do it, and I have seen real-world applications that do that, but I don't recommend it. It is overkill for the simple CRUD case and is unhelpful for the more complex cases (where you actually want a transaction to span several DAO calls). It leaves you with a lot of code that doesn't do much. The DAOs can be specified using Spring Data, the services will be boilerplate with each method wrapping a call to a DAO. Spring should help reduce boilerplate as opposed to mandating it.

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

If you have a totally CRUD application then you can legitimately do without services, put @Transactional on the DAOs, and call the DAO from the Controller. If the service is not pulling its weight get rid of it.

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

If you do have actual business logic in the application then when a user invokes something that can involve calls to different DAOs, those calls should usually take place within the same transaction so that if one thing fails everything gets rolled back. (Also creating a transaction is relatively expensive and if you have a controller making calls to different services for different entities then that will be slow.) That is where services come in handy, the service specifies the low-level use cases that the user wants to perform and allows transactional behavior to be specified.

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

For the CRUD case I would prefer using a tool like Grails or Play or Rails or something to writing Java with Spring MVC. Grails, for instance, will generate views and controllers for you, provide basic data access through GORM (so there are no DAOs to write), and it will let you specify services easily for the cases where you find you need them.

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

回答by Sanjaya Liyanage

No there is no need to have 30 service layers or 30 dao layers.you should specify the layers not considering the Entity wise but the business functionality wise.there can be 5 or 6 entities relevant for certain function and those should be in one layer.But still you will have to have getXById(), deleteX(x), createX(x) in those redundant layers if they are required.

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