将数组参数绑定到本机查询

HAY*_*bl4 5 java sql postgresql hibernate jpa

我有表product_spec_entry,包含以下列:

  • product_spec_id
  • commodity_spec_id

对于一个product_spec_id可能是几个commodity_spec_id,例如:

|product_spec_id | commodity_spec_id|
|----------------|------------------|
|1683            |1681              |
|1692            |1693              |
|1692            |1681              |
|1692            |1687              |
|1692            |1864              |
|1860            |1681              |
|1868            |1681              |
|1868            |1864              |
Run Code Online (Sandbox Code Playgroud)

我希望得到所有具有所有commodity_spec_id的product_spec_id作为参数传递.

我写了下一个查询:

SELECT ps.product_spec_id, commodities
FROM (
       SELECT
         product_spec_id,
         array_agg(commodity_spec_id) AS commodities
       FROM system.product_spec_entry
       GROUP BY product_spec_id) ps
WHERE Cast(ARRAY [1681, 1864] as BIGINT[]) <@ Cast(ps.commodities as BIGINT[]);
Run Code Online (Sandbox Code Playgroud)

它工作正常,并返回预期的结果:

product_spec_id = 1692,1868

我尝试将此查询用于JPA本机查询:

String query = "SELECT ps.product_spec_id " +
                "FROM ( " +
                "       SELECT " +
                "         product_spec_id, " +
                "         array_agg(commodity_spec_id) AS commodities " +
                "       FROM system.product_spec_entry " +
                "       GROUP BY product_spec_id) ps " +
                "WHERE CAST(ARRAY[:commoditySpecIds] AS BIGINT[]) <@ CAST(ps.commodities AS BIGINT[])";
List<Long> commoditySpecsIds = commoditySpecs.stream().map(Spec::getId).collect(Collectors.toList());

List<BigInteger> productSpecIds = em.createNativeQuery(query).setParameter("commoditySpecIds", commoditySpecsIds)
                .getResultList();
Run Code Online (Sandbox Code Playgroud)

它不起作用因为我得到了record(ARRAY[(1692, 1868)])数组而不是bigint数组(ARRAY[1692, 1868])

我应该如何将数组参数绑定到我的查询?可能是我可以使用更简单的查询.

a_h*_*ame 8

array[...]从您的 SQL 中删除:

WHERE CAST(:commoditySpecIds AS BIGINT[])
Run Code Online (Sandbox Code Playgroud)

然后将 ID 列表作为如下所示的字符串传递:

"{1,2,3,4}"
Run Code Online (Sandbox Code Playgroud)

Lists 的默认 toString() 通常返回类似的内容:"[1,2,3]",因此您可以执行以下操作:

String literal = commoditySpecsIds.toString();
literal = "{" + literal.substring(1,literal.length() - 1) + "};
Run Code Online (Sandbox Code Playgroud)

然后将其传递给您的混淆层:

setParameter("commoditySpecIds", literal)
Run Code Online (Sandbox Code Playgroud)


Jer*_*ont 5

我的情况完全一样。希望@VladMihalcea 可以帮助我们

编辑

我想出来用JPA来做。在阅读了 setParameter 的实现之后,我发现了一些类似于 UserType,TypedParameterValue 的东西。

当你使用

setParameter("commoditySpecIds", new TypedParameterValue(IntArrayType.INSTANCE, commoditySpecsIds))
Run Code Online (Sandbox Code Playgroud)

其中 IntArrayType.INSTANCE 来自 Vlad Mihalcea 提供的“休眠类型”库。注意,“commoditySpecsIds”必须是一个数组,而不是一个集合。

希望有帮助