我使用Vlad Mihalcea的库来将SQL数组(在我的情况下为Postgresql)映射到JPA。然后让我们想象我有一个实体,例如。
@TypeDefs(
{@TypeDef(name = "string-array", typeClass =
StringArrayType.class)}
)
@Entity
public class Entity {
@Type(type = "string-array")
@Column(columnDefinition = "text[]")
private String[] tags;
}
适当的SQL是:
CREATE TABLE entity (
tags text[]
);
使用QueryDSL我想获取标签包含所有给定标签的行。原始SQL可以是:
SELECT * FROM entity WHERE tags @> '{"someTag","anotherTag"}'::text[];
(摘自:https://www.postgresql.org/docs/9.1/static/functions-array.html)
是否可以使用QueryDSL执行此操作?下面的代码有点像?
predicate.and(entity.tags.eqAll(<whatever>));
WHERE tags @> '{"someTag","anotherTag"}'::text[];
predicate.and(Expressions.booleanTemplate("arraycontains({0}, string_to_array({1}, ','))=true", entity.tags, tagsStr));
其中tagsStr
- 是一个String
与由,
分隔的值由于您无法使用自定义运算符,因此必须使用其功能等价物。您可以使用\doS+
在psql控制台中查找它们。对于\doS+ @>
,我们得到了几个结果,但这是你想要的结果:
List of operators
Schema | Name | Left arg type | Right arg type | Result type | Function | Description
------------+------+---------------+----------------+-------------+---------------------+-------------
pg_catalog | @> | anyarray | anyarray | boolean | arraycontains | contains
它告诉我们使用的函数叫做arraycontains
,所以现在我们使用\df arraycontains
查找该函数来查看它的参数
List of functions
Schema | Name | Result data type | Argument data types | Type
------------+---------------+------------------+---------------------+--------
pg_catalog | arraycontains | boolean | anyarray, anyarray | normal
从这里,我们将您的目标查询转换为:
SELECT * FROM entity WHERE arraycontains(tags, '{"someTag","anotherTag"}'::text[]);
然后,您应该能够使用构建器的function
调用来创建此条件。
ParameterExpression<String[]> tags = cb.parameter(String[].class);
Expression<Boolean> tagcheck = cb.function("Flight_.id", Boolean.class, Entity_.tags, tags);
虽然我使用不同的阵列解决方案(可能会很快发布),但我相信它应该可行,除非底层实现中存在错误。
方法的替代方法是编译数组的转义字符串格式并将其作为第二个参数传递。如果不将双引号视为可选,则更容易打印。在那种情况下,玩具必须在上面的String[]
排中用String
替换ParameterExpression
对于EclipseLink,我创建了一个函数
CREATE OR REPLACE FUNCTION check_array(array_val text[], string_comma character varying ) RETURNS bool AS $$
BEGIN
RETURN arraycontains(array_val, string_to_array(string_comma, ','));
END;
$$ LANGUAGE plpgsql;
正如Serhii所指出的那样,你可以使用Expressions.booleanTemplate("FUNCTION('check_array', {0}, {1}) = true", entity.tags, tagsStr)