Spring Data Repository:托管类型是什么?

Spring Data Repository: What is the managed type?

就我的意图而言,org.springframework.data.repository.Repository 的 JavaDoc 在通用参数 <T> 上有点不精确。它说:

@param the domain type the repository manages

好的。

假设我们有这些实体:

@Entity
@Table
public class Parent {
    @Id
    private Long id;

    @Getter
    @OrderBy
    @OneToMany(mappedBy = "parent")
    private Set<Children> children;
}

@Entity
@Table
public class Children {
    @Id
    private Long id;

    @OneToOne
    @JoinColumn(name = "parent_id", nullable = false)
    private Parent parent;
}

如果查询一个父项的所有子项,哪个存储库是正确的?

public interface ParentRepository extends Repository<Parent, Long> {
    // IntelliJ Warning: 'Children' domain type or valid projection interface expected here
    @Query("SELECT children FROM Parent WHERE id = ?1")
    List<Children> getChildrenByParentId(Long parentId);
}

public interface ChildrenRepository extends Repository<Children, Long> {
    @Query("SELECT children FROM Parent WHERE id = ?1")
    List<Children> getChildrenByParentId(Long parentId);
}

这个额外的查询怎么样?

@Query("SELECT parent.children FROM Parent parent LEFT JOIN parent.children children WHERE parent.id = ?1 ORDER BY children.id")
List<Children> getOrderedChildrenByParentId(Long parentId);

因为无论使用哪个存储库它都能正常工作,我更感兴趣的是为什么 ParentRepositoryChildrenRepository 是正确的。

浏览文档后:https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#reference ParentRepository 似乎更正确 - 尽管 IntelliJ 警告。

如果创建接口:

public interface ParentRepository extends Repository<Parent, Long>

参数Parent用于生成findAll、findOne等方法return正确的类型,参数Long用作主键类型。

如果你这样做:

@Query("SELECT parent.children FROM Parent parent LEFT JOIN parent.children children WHERE parent.id = ?1 ORDER BY children.id")
List<Children> getOrderedChildrenByParentId(Long parentId);

您完全可以自由选择要使用的参数类型和 return 类型。因此,将带有@Query 注释的方法放在哪里并不重要。