【问题标题】:Understanding repositories in Spring Data了解 Spring Data 中的存储库
【发布时间】:2017-05-23 18:02:59
【问题描述】:

我想创建一个从多个实体查询数据的“通用”存储库。如果我这样做:

@Repository
public interface MyRepository {

    @Query("select r from Role r")
    List<Role> getRoles();

}

我收到一个错误,因为当需要 MyRepository 实例时,Spring 找不到要注入的实现。到目前为止,一切都很好。现在,如果我这样做:

@Repository
public interface MyRepository extends JpaRepository {

    @Query("select r from Role r")
    List<Role> getRoles();

}

我收到一个错误,因为 Object 不是 JPA 托管类型(JpaRepository 是通用的)。好的,再次。如果我这样做:

@Repository
public interface MyRepository extends JpaRepository<User, String> {

    @Query("select r from Role r")
    List<Role> getRoles();

} 

它有效。为什么?我为实体用户声明了一个 JpaRepository,而不是角色。为什么 JpaRepository 需要一个具体实体,即使查询将针对另一个实体?

【问题讨论】:

  • 因为它还定义了其他方法,例如findAllfindOne 等,在这种情况下,这些方法仅适用于User。当您使用 @Query 指定方法时,它会查看方法签名。
  • 即使我只想使用@Query 进行查询,是否也必须扩展 JpaRepository?
  • 为什么你甚至需要一个查询呢?只需创建一个RoleRepository extends JpaRepository&lt;Role, Long&gt; 并使用findAll 方法。但理论上你可以扩展Repository 而不是JpaRepository 但是你为什么要使用Spring Data JPA?你失去了所有的好处。

标签: spring spring-data spring-data-jpa


【解决方案1】:

Spring Data 中的每个存储库都必须扩展 Repository 接口,这是一个通用接口,因此您始终必须指定要使用的实体,而您无能为力,因为 Spring Data 就是这样实施的。您可以在此处找到有关创建存储库的更多信息:

http://docs.spring.io/spring-data/jpa/docs/1.4.0.M1/reference/html/repositories.html

另一方面,您当然可以为存储库指定一个实体,然后添加返回其他类型实体的方法,因为在您的界面中您可以添加任何您想要的东西(还要注意存储库接口没有方法)。但是如果你想使用父接口的方法,你必须使用你指定的实体。

在你的例子中,你可以做什么@M。 Deinum 建议并创建一个JpaRepository&lt;Role, Long&gt; 并使用findAll 查询,这更有意义。使用JpaRepository&lt;User, String&gt; 只是对框架的滥用。

【讨论】:

  • 我只是想避免拥有 30 个不同的 {Entity}Repository。将它们全部放在一个界面中会很好。
猜你喜欢
  • 2012-07-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-06
  • 2017-09-07
  • 2017-04-30
  • 2016-12-26
相关资源
最近更新 更多