gpt4 book ai didi

java - HQL 或 SQL 查询从许多相关实体获取数据

转载 作者:行者123 更新时间:2023-11-29 15:42:17 26 4
gpt4 key购买 nike

我使用 spring 和 hibernate 将数据存储在 MySql 数据库中。我正在尝试根据用户请求的过滤器检索行。我有以下表格/实体:产品和 gem

关系:
  • 产品多对多 gem

我正在尝试编写一个查询来获取具有 gem A、 gem B 和 gem C 等的产品。

用例:

如果用户请求 gem 为 51 和 46 的产品。查询应仅返回产品 ID 4。

查询:

filterGemstones() 方法返回用户想要过滤产品的 gem 。使用下面的查询我得到零条记录,但如果我删除 HAVING Count(DISTINCT p.product_id) = 2 我得到产品 id 4, 5

two muppets

  • HQL:

    createQuery("select p.productId from Product p JOIN p.gemstones g where g in :gemstones group by p having count (distinct p) =" +  filterGemstones().size() ).setParameter("gemstones",filterGemstones());
  • 由 hibernate 生成 SQL :

    SELECT p.product_id 
    FROM product p
    INNER JOIN gemstone_product gp
    ON p.product_id = gp.product_id
    INNER JOIN gemstone g
    ON gp.gemstone_id = g.gemstone_id
    WHERE g.gemstone_id IN ( 51, 46 )
    GROUP BY p.product_id
    HAVING Count(DISTINCT p.product_id) = 2

产品类别:

@Entity
@Table(name = "product")
public class Product {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "product_id")
private long productId;

@ManyToMany()
@JoinTable(
name = "gemstone_product",
joinColumns = {@JoinColumn(name = "product_id")},
inverseJoinColumns = {@JoinColumn(name = "gemstone_id")}
)
private Set<Gemstone> gemstones = new HashSet<>(0);

// setters and getters
}

gem 类别:

@Entity
@Table(name = "gemstone")
public class Gemstone {

@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name = "gemstone_id")
private long gemstoneId;

@ManyToMany(fetch = FetchType.LAZY)
@JoinTable(
name = "gemstone_product",
joinColumns = {@JoinColumn(name = "gemstone_id")},
inverseJoinColumns = {@JoinColumn(name = "product_id")}
)
private Set<Product> products = new HashSet<>(0);

// setters and getters
}

最佳答案

实际上我们需要的 SQL 查询非常简单:

SELECT t1.product_id 
FROM gemstone_product AS t1
WHERE (t1.gemstone_id IN ?1 ) # (51, 46)
GROUP BY t1.product_id
HAVING (COUNT(t1.gemstone_id) = ?2) # 2 - # of items

有点沮丧的是,用JPA创建它并不容易,但是用 FluentJPA 就可以完成(产生上面的查询):

public List<Integer> getProductsContainingAllStones(List<Long> gemstoneIds) {
int count = gemstoneIds.size();

FluentQuery query = FluentJPA.SQL((Gemstone gemstone,
JoinTable<Gemstone, Product> gemstoneProduct) -> {

discardSQL(gemstoneProduct.join(gemstone, Gemstone::getProducts));

long productId = gemstoneProduct.getInverseJoined().getProductId();
long gemstoneId = gemstoneProduct.getJoined().getGemstoneId();

SELECT(productId);
FROM(gemstoneProduct);
WHERE(gemstoneIds.contains(gemstoneId));
GROUP(BY(productId));
HAVING(COUNT(gemstoneId) == count);
});
return query.createQuery(em).getResultList();
}

有关其工作原理的更多详细信息,请访问 here .

关于java - HQL 或 SQL 查询从许多相关实体获取数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57486892/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com