Spring Data JPA中的多个基础存储库

6
我目前正在将一个使用Hibernate ORM自己管理JPA的应用程序迁移到Spring Boot 2.0.0和Spring Data JPA 2.0.0。该应用程序目前有大约50个实体,每个实体都有自己的数据源,现在我想将它们迁移到Spring Data Repositories。其中许多数据源具有许多相似的功能,例如使用自定义过滤器类进行过滤或通过某种唯一键获取实体而不是其ID。我可以按照Spring Data JPA Reference中描述的实现自定义基类,但这意味着我必须为每个实体提供自定义过滤器,而我只需要为其中的10个提供。是否有可能像下面展示的那样让Spring Data合并多个自定义存储库实现?

实体:

@Entity
public class Artist {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    int id;

    @Column(unique = true)
    int secondaryId;
    String name;

    ... constructors, getter, setter, etc ...
}    

@Entity
public class Album {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    int id;

    String name;

    ... constructors, getter, setter, etc ...
}

具有默认实现的自定义存储库:

public interface FilterRepository<T> {
    public T findByFilter(Filter<T> t);
}

public class FilterRepositoryImpl<T> implements AdditionalRepository<T> {
    public T findByFilter(Filter<T> t) {
        ... return something ...
    }
}

public interface FindByFieldRepository<T> {
    public T findByField(String fieldName, Object fieldValue);
}

public class FindByFieldRepositoryImpl<T> implements FindByFieldRepository<T> {
    public T findByField(String fieldName, Object fieldValue) {
        ... return something ...
    }
}

Spring Data仓库

@Repository
public interface ArtistRepository extends JpaRepository<Artist, Integer>, 
        FilterRepository<Artist>, FindByFieldRepository<Artist> {
}

@Repository
public interface AlbumRepository extends JpaRepository<Album, Integer>, 
        FilterRepository<Album> {
}

请注意,ArtistRepository 扩展了两个自定义仓库,而 AlbumRepository 仅扩展了 FilterRepository。另一个仓库可能会扩展 JpaRepository,但没有任何自定义定义的仓库扩展它们。
1个回答

4
这应该可以通过两个接口和一个自定义的存储库实现。例如:

步骤1:扩展JpaRepository

@NoRepositoryBean
public interface FilteringJpaRepository<T> extends JpaRepository<T, Long> {
  T findByFilter(Filter<T> t);
}

步骤2:更复杂的JpaRepository扩展。
@NoRepositoryBean
public interface ExtendedJpaRepository<T> extends FilteringJpaRepository<T> {
  T findByField(String fieldName, Object fieldValue);
}
步骤3:自定义存储库实现
按照问题中链接的文档描述添加自定义存储库实现。还要确保更改JPA配置以使用自定义实现。
@NoRepositoryBean
public class ExtendedJpaRepositoryImpl<T>
             extends SimpleJpaRepository<T, Long>
             implements ExtendedJpaRepository<T> {
  ...

  public T findByFilter(Filter<T> t) { ... }

  public T findByField(String fieldName, Object fieldValue) { ... }
}

步骤4:根据需要从适当的存储库扩展
public interface AlbumRepository extends FilteringJpaRepository<Album> {}

public interface ArtistRepository extends ExtendedJpaRepository<Artist> {}

功能存储库仅扩展所需的存储库,因此它们的使用者只能看到适合他们的方法。


请参见示例应用程序以了解这种方法。


1
虽然这不是我能想到的最漂亮的解决方案,但肯定是可行的。我唯一仍然存在的“问题”是,我不仅有两个自定义存储库,而且还有大约5或6个(或将来更多),我无法将它们放入任何层次结构中,并且一个实现所有这些接口的类有点丑陋。 - Florian Cramer
嗨,我的存储库设置与您相同,我有一个基本存储库(用@NoRepositoryBean注释),它扩展了Spring的CrudRepository,并且我有单独的存储库接口,这些接口扩展了我的基本存储库。我发现的一个问题是,在我的数据库中,所有实体类数据都在每个实体表中 - 我正在尝试找出这是否与此有关。 - Effie Makri

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接