【问题标题】:JPA Specification multiple join based on foreignkeyJPA规范基于外键的多重连接
【发布时间】:2020-06-07 00:48:11
【问题描述】:

我在三个对象之间有以下关系

public class ProductEntity {
    @Id
    private int id;

    @OneToMany(mappedBy = "productEntity",
               fetch = FetchType.LAZY)
    private List<ProductInfoEntity> productInfoEntityList = new ArrayList<>();

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

public class ProductInfoEntity {
    @Id
    private int id;

    @ManyToOne
    @JoinColumn(name = "product_id")
    private ProductEntity productEntity;

    @ManyToOne
    @JoinColumn(name = "support_language_id")
    private SupportLanguageEntity supportLanguageEntity;
}


public class SupportLanguageEntity {
    @Id
    private int id;

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

这是实际的数据库设计

那么,我想制定一个规范来查询如下:

从产品信息中选择 * 其中product_id = 1 和 support_language_id = 2;

我也在为规范使用注解,这意味着我使用 ProductEntity_、ProductInfoEntity_ 等。

能否请您给我上述查询规范的完整工作代码?

谢谢大家

【问题讨论】:

  • 抱歉,SO 不是编码服务。我们不会为您编写代码。但是,如果您尝试过某事但无法使其发挥作用,请告诉我们您尝试了什么,它是如何无效的,我相信有人会给出如何继续的提示。
  • 感谢您纠正我,但我什至不知道如何做到这一点。我已经搜索了 SO,但找不到我的问题的答案。那么,你能给我一些提示吗?

标签: mysql spring-mvc jpa spring-data-jpa specifications


【解决方案1】:

要使用Specification 你的ProductInfoEntityRepository 必须扩展JpaSpecificationExecutor

@Repository
public interface ProductInfoEntityRepository 
    extends JpaRepository<ProductInfoEntity, Integer>, JpaSpecificationExecutor<ProductInfoEntity> {
}

据我了解,您使用JPA 元模型。那么

@Autowired    
ProductInfoEntityRepository repository;

public List<ProductInfoEntity> findProductInfoEntities(int productId, int languageId) {
    return repository.findAll((root, query, builder) -> {
        Predicate productPredicate = builder.equal(
                root.get(ProductInfoEntity_.productEntity).get(ProductEntity_.id), // or root.get("productEntity").get("id")
                productId); 

        Predicate languagePredicate = builder.equal(
                root.get(ProductInfoEntity_.supportLanguageEntity).get(SupportLanguageEntity_.id),  // or root.get("supportLanguageEntity").get("id")
                languageId);

        return builder.and(productPredicate, languagePredicate);
    });
}

如果您想使规范可重用,您应该创建包含两个静态方法productIdEquals(int)languageIdEquals(int) 的实用程序类。

要将它们组合使用Specifications(Spring Data JPA 1.*) 或 Specification(自 Spring Data JPA 2.0)

【讨论】:

  • 感谢您的回答。我已经成功了!!!!谢谢
【解决方案2】:
select * from product_info where product_id = 1 and support_language_id = 2;

应该按书面规定工作。但唯一有用的是comment

也许您想要所有三个表中的其余信息?

SELECT  pi.comment,   -- list the columns you need
        p.snippet,
        sl.name
    FROM product AS p      -- table, plus convenient "alias"
    JOIN product_info AS pi  -- another table
        ON p.id = pi.product_info  -- explain how the tables are related
    JOIN support_language AS sl  -- and another
        ON pi.support_language_id = sl.id  -- how related
    WHERE  p.snippet = 'abc'   -- it is more likely that you will start here
    -- The query will figure out the rest.

从那里,看看你是否可以解决 JPA 提供的混淆。

【讨论】:

    猜你喜欢
    • 2021-06-22
    • 1970-01-01
    • 2017-10-14
    • 2021-09-07
    • 2017-05-12
    • 2023-03-24
    • 2018-02-05
    • 2013-07-30
    • 1970-01-01
    相关资源
    最近更新 更多