JPA规范:基于外键的多重连接

4

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

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;
}

这是实际的数据库设计: enter image description here 然后,我想要制定以下查询规范:
select * from product_info where product_id = 1 and support_language_id = 2;
我还使用了注释来说明规范,这意味着我使用ProductEntity_、ProductInfoEntity_等。请问您能否为上述查询规范提供完整的工作代码?
谢谢!

1
抱歉,但SO不是编程服务。我们不会为您编写代码。但是,如果您已经尝试过某些方法但无法使其正常工作,请告诉我们您尝试了什么,它出现了什么问题,我相信有人会给出提示如何继续进行。 - Jens Schauder
谢谢您纠正我,但我甚至不知道如何做这个。我已经在SO上搜索过了,但没有找到我的问题的答案。那么,您能给我一些提示吗? - kisung Tae
2个回答

3

要使用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开始)。

1
谢谢您的回答。我已经让它工作了!!!谢谢。 - kisung Tae

0
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提供的混淆。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接