当前位置: 首页 > 知识库问答 >
问题:

Spring Data JPA,CrudRepository接口中的parametrize@EntityGraph

冉子石
2023-03-14
public interface UserDao extends CrudRepository<User, Long> {

@EntityGraph(value = :graphName, type = EntityGraph.EntityGraphType.LOAD)
    @Query(value = "SELECT DISTINCT u FROM User u")
    List<User> findAllWithDetailsByGraphName(@Param(value="graphName") String graphName);

}
@Entity
@Table(name="user")
@NamedEntityGraphs({
        @NamedEntityGraph(name = "User.details", attributeNodes = {
                @NamedAttributeNode("phones"), @NamedAttributeNode("emails"), @NamedAttributeNode("pets")}),
        @NamedEntityGraph(name = "User.phones", attributeNodes =
                {@NamedAttributeNode("phones")}),
        @NamedEntityGraph(name = "User.emails", attributeNodes =
                {@NamedAttributeNode("emails")}),
        @NamedEntityGraph(name = "User.pets", attributeNodes =
                {@NamedAttributeNode("pets")})
})
public class User {
    @Id
    @GeneratedValue(strategy= GenerationType.AUTO, generator="native")
    @GenericGenerator(name = "native", strategy = "native")
    @Column(name="user_id")
    private Long userId;

    @Column(name="name")
    private String name;

// more fields omitted

    @OneToMany(mappedBy = "user", cascade = CascadeType.ALL)
    private Set<Phone> phones;

    @OneToMany(mappedBy = "user", cascade = CascadeType.ALL)
    private Set<Email> emails;

    @OneToMany(mappedBy = "user", cascade = CascadeType.ALL)
    private Set<Pet> pets;
}

现在,我只需隐式声明所有方法,如下所示:

@EntityGraph(value = "User.phones", type = EntityGraph.EntityGraphType.LOAD)
@Query(value = "SELECT DISTINCT u FROM User u")
List<User> findAllWithPhones();

向你请教建议!

共有1个答案

李利
2023-03-14

您可以定义一个接受实体图作为参数的基本JPA存储库。这与规范结合使用特别有用。因此,下面是一个基于规范的示例。还可以使用不同类型的参数构造其他查询。

@NoRepositoryBean
public interface MyBaseRepository<T, ID extends Serializable> extends PagingAndSortingRepository<T, ID> {

    T findOne(Specification<T> spec, EntityGraphType entityGraphType, String entityGraphName);

    List<T> findAll(Specification<T> spec, Sort sort, EntityGraphType entityGraphType, String entityGraphName);

}

实现基本存储库:

@NoRepositoryBean
public class MyBaseRepositoryImpl<T, ID extends Serializable> extends SimpleJpaRepository<T, ID> implements MyBaseRepository<T, ID> {

    private EntityManager em;

    public MyBaseRepositoryImpl(JpaEntityInformation<T, ?> entityInformation, EntityManager entityManager) {
        super(entityInformation, entityManager);
        this.em = entityManager;
    }

    public MyBaseRepositoryImpl(Class<T> domainClass, EntityManager em) {
        super(domainClass, em);
        this.em = em;
    }

    @Override
    public T findOne(Specification<T> spec, EntityGraph.EntityGraphType entityGraphType, String entityGraphName) {
        TypedQuery<T> query = getQuery(spec, (Sort) null);
        query.setHint(entityGraphType.getKey(), em.getEntityGraph(entityGraphName));
        return query.getSingleResult();
    }

    @Override
    public List<T> findAll(Specification<T> spec, Sort sort, EntityGraph.EntityGraphType entityGraphType, String entityGraphName) {
        TypedQuery<T> query = getQuery(spec, sort);
        query.setHint(entityGraphType.getKey(), em.getEntityGraph(entityGraphName));
        return query.getResultList();
    }

}

指定自定义基本存储库:

<jpa:repositories base-package="my.domain" base-class="my.repository.MyBaseRepositoryImpl" />
public interface UserRepository extends JpaRepository<User, Long>, MyBaseRepository<User, Long>, JpaSpecificationExecutor<User> {
}
Specification mySpecs = ...
List<User> user = picklistRepository.findAll(mySpecs, EntityGraphType.LOAD, "User.phones");
 类似资料:
  • 我需要创建一个实现接口的类吗?如果是,如何实施?有什么例子吗?或者我只是把它留空然后Spring来做这些工作? 我使用以下简单代码进行尝试: loginbean.java 但我得到 更新 好的,我发现了问题,是因为我的autowired accountRepository是空的,你知道吗?

  • 问题内容: Spring Data JPA 和接口之间有什么区别? 当我在网络上看到示例时,我发现它们在这里可以互换使用。它们之间有什么区别?你为什么要在另一个上使用? 问题答案: 延伸,延伸。 它们的主要功能是: 主要提供CRUD功能。 提供进行分页和排序记录的方法。 提供了一些与JPA相关的方法,例如刷新持久性上下文和批量删除记录。 由于继承如上所述, 将所有的功能和。所以,如果你不需要的仓库

  • 我有一个重要的问题: null 这是一个简单的4步过程: 定义属性 定义您的实体 定义扩展CrudRepository和的接口 使用该接口 但是在使用两个数据库的情况下,有一个5。必须定义类的步骤。 您也可以在一门课上同时上两门课,但我是这样做的: db1config.java java db2config.java 谢谢你的帮助。

  • 我的项目中的三个模型对象(本文末尾的模型和存储库片段)之间确实存在关系。 当我调用时,它会触发三个select查询: (“sql”) (对我来说)那是相当不寻常的行为。在阅读Hibernate文档后,我认为它应该始终使用连接查询。当类中的更改为时,查询没有区别(使用附加选择进行查询),当更改为时,城市类的查询也一样(使用JOIN进行查询)。 当我使用抑制火灾时,有两种选择: 我的目标是在所有情况下

  • 问题内容: 我有一个定义方法的接口。我有一个 实现 此接口的结构。在其中,我已经从该接口实现了方法,并且还定义了其他方法。 例如: 在操场上:https : //play.golang.org/p/B1GgoNToNl_l 在此,WagTail()不是Animal接口的一部分,但属于Dog结构。运行此代码会出现错误 dog.WagTail未定义(动物类型没有字段或方法WagTail)。 有没有一种

  • 为什么它这样做,它有一个更好的做法?在sub接口中实现方法有什么区别吗?