【问题标题】:Is it necessary to create an repository and a service for each entity? [duplicate]是否有必要为每个实体创建存储库和服务? [复制]
【发布时间】:2015-08-23 11:44:38
【问题描述】:

我正在使用 Hibernate+Spring 和一个数据库来保存我的实体。我已经在使用JpaRepository 创建我的存储库,但即便如此,我似乎必须为每个实体创建一个扩展 JpaRepository 的接口。最糟糕的是,我正在为每个实体创建一项服务。他们都非常相似。

有什么方法可以创建通用服务和通用存储库?真的有必要逐一实现吗?

目前,我有这样的存储库:

@Repository
public interface PhaseRepository extends JpaRepository<Phase, Serializable> {

}

还有这样的服务:

@Service
public class PhaseService {
    @Autowired
    PhaseRepository repository;

    @Transactional
    public Phase create(Phase entity) {
        return repository.save(entity);
    }

    @Transactional(rollbackFor = EntityNotFound.class)
    public Phase delete(int id) throws EntityNotFound {
        Phase deleted = repository.findOne(id);
        if (deleted == null) {
            throw new EntityNotFound();
        }
        repository.delete(deleted);
        return deleted;
    }

    @Transactional(rollbackFor = EntityNotFound.class)
    public Phase update(Phase entity) throws EntityNotFound {
        Phase updated = repository.findOne(entity.getId());

        if (updated == null) {
            throw new EntityNotFound();
        }

        repository.saveAndFlush(entity);
        return updated;
    }

    public Phase findById(int id) throws EntityNotFound {
        Phase entity = repository.findOne(id);

        if (entity == null) {
            throw new EntityNotFound();
        }

        return entity;
    }
}

我使用了 12 个实体,每个人都有相同的服务方法。

谢谢!

【问题讨论】:

    标签: java spring hibernate jpa


    【解决方案1】:

    您可能需要 12 个存储库。但也许你不需要 12 项服务。一个服务可以处理对多个存储库的访问。这取决于您的逻辑以及每个实体的“重要性”程度。

    例如,如果您有实体 User 和 Address,您可以有 UserRepository 和 AddressRepository。但只有 UserService,使用 addAddress(User user, Address address) 之类的方法...

    总而言之,我建议您根据业务逻辑而不是一堆 CRUD 来组织您的服务

    【讨论】:

      【解决方案2】:

      您需要 12 个存储库,因为 Spring 会初始化您声明的接口的实例。 Spring 已经做得很好了,我认为这里没有问题。想象一下过去的情况,您必须通过样板 JDBC 代码来实现这些存储库。

      但您的存储库不会自动需要服务。为您的应用程序目的创建服务并在其中自动装配必要的存储库。但是我已经创建了一个示例代码,如果您想要没有复制粘贴代码的通用服务:

      public abstract class AbstractService<T extends AbstractEntity, K extends Serializable> {
      
          protected JpaRepository<T, K> repository;
      
          public AbstractService(final JpaRepository<T, K> repository) {
              this.repository = repository;
          }
      
          @Transactional(rollbackFor = EntityNotFound.class)
          public T delete(final K id) throws EntityNotFound {
              final T deleted = this.repository.findOne(id);
              if (deleted == null) {
                  throw new EntityNotFound();
              }
              this.repository.delete(deleted);
              return deleted;
          }
      
          ...
      
      }
      

      实现类是:

      @Service
      public class PhaseService extends AbstractService<PhaseEntity, Integer> {
      
          @Autowired
          public PhaseService (final PhaseRepository repository) {
              super(repository);
          }
      
      }
      

      还有一些提示:

      • 您不需要 EntityNotFound 异常。只需检查实体是否为空。
      • 使用主键强类型代替可序列化 - 例如整数。

      【讨论】:

        猜你喜欢
        • 2023-04-01
        • 2011-11-10
        • 2012-08-21
        • 2012-03-10
        • 1970-01-01
        • 1970-01-01
        • 2021-03-21
        • 2015-12-04
        • 2016-02-01
        相关资源
        最近更新 更多