使用AttributeConverter存储的列表中项目的JPQL查询

时间:2018-05-15 17:15:11

标签: java mysql hibernate jpa-2.1

正如Tobias Liefke建议here,我已经实现了AttributeConverter来将列表值存储到以逗号分隔的单个字符串列中。

转换器类:

public class ListNumbersConverter implements AttributeConverter<List<Long>, String>

实体类中的字段:

@Column(name = "user_ids", nullable = false)
@Convert(converter = ListNumbersConverter.class)
private List<Long> userIds;

它工作正常,但我无法查询特定列表项的记录。我尝试在JPQL查询中使用IN运算符,如下所示:

? in userIds 

如果输入参数是DB值中的第一个元素,那么我只得到一个结果。例如:DB值为“1,2,3”。如果上述查询的输入参数值为1,我能够检索此记录,但如果值为2或3则无法检索。如何编写查询以检索包含特定项目的所有记录?< / p>

我的数据库是MySQL。

1 个答案:

答案 0 :(得分:0)

Hibernate并不知道 转换器如何将列表映射到列。它无法构建从JPQL ? in userIds到匹配的SQL片段的映射,因为它需要知道如何实现转换器。

但是你总是可以自己构建那个SQL片段,例如:

WHERE concat(',', entity.userIds, ',') LIKE concat('%,', ?, ',%')

第一个concat是确保表达式甚至匹配列表的第一个和最后一个值(不会以分隔符开头或结尾)。

可以使用其他特定于数据库的函数,但此示例适用于我所知道的所有数据库类型。

另一个评论:您不应该尝试在查询中加入userIds - 因为它是基本类型,即使它是一个列表。请参阅@Convert的JavaDoc:

  

转换注释用于指定基本字段或的转换   属性。

然而,如果您将属性直接与文字(entity.userIds = '1')进行比较,Hibernate会抱怨,因为属性的类型与文字的类型不匹配。但只要您在比较的任何一方使用上述功能,它就不会抱怨。