JPA Спецификация множественного объединения на основе Foreignkey - PullRequest
3 голосов
/ 23 февраля 2020

У меня есть следующие отношения между тремя объектами

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

Затем я хотел бы сделать спецификацию сделать запрос следующим образом:

выберите * из product_info, где product_id = 1 и support_language_id = 2;

Я также использую аннотацию для спецификации, что означает, что я использую ProductEntity_, ProductInfoEntity_ и так далее.

Не могли бы вы дать мне полный рабочий код спецификации для запроса, упомянутого выше?

Спасибо, ребята

Ответы [ 2 ]

2 голосов
/ 25 февраля 2020

Для использования Спецификация ваш 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);
    });
}

Если вы хотите сделать спецификации многоразовыми, вы должны создать служебный класс, содержащий два метода c * * * * * * * * и languageIdEquals(int).

Чтобы объединить их, используйте Технические характеристики (Spring Data JPA 1. *) или Спецификация (начиная с Spring Data JPA 2.0)

0 голосов
/ 25 февраля 2020
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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...