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

Flo*_*mer 6 java spring-data-jpa

我目前正在将一个以 Hibernate ORM 形式管理 JPA 的应用程序本身迁移Spring Boot 2.0.0Spring 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 ...
}
Run Code Online (Sandbox Code Playgroud)

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

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 ...
    }
}
Run Code Online (Sandbox Code Playgroud)

Spring 数据存储库

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

@Repository
public interface AlbumRepository extends JpaRepository<Album, Integer>, 
        FilterRepository<Album> {
}
Run Code Online (Sandbox Code Playgroud)

请注意,ArtistRepository扩展了两个自定义存储库,而AlbumRepository仅扩展了FilterRepository。另一个存储库可能会扩展JpaRepository,但不会扩展自定义的存储库。

man*_*ish 4

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

第 1 步:简单扩展JpaRepository

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

步骤 2:更复杂的扩展JpaRepository

@NoRepositoryBean
public interface ExtendedJpaRepository<T> extends FilteringJpaRepository<T> {
  T findByField(String fieldName, Object fieldValue);
}
Run Code Online (Sandbox Code Playgroud)

第 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) { ... }
}
Run Code Online (Sandbox Code Playgroud)

步骤 4:根据需要从适当的存储库进行扩展

public interface AlbumRepository extends FilteringJpaRepository<Album> {}

public interface ArtistRepository extends ExtendedJpaRepository<Artist> {}
Run Code Online (Sandbox Code Playgroud)

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


请参阅此方法的示例应用程序。