【问题标题】:JPQL query for item in list stored with AttributeConverterJPQL 查询使用 AttributeConverter 存储的列表中的项目
【发布时间】:2018-10-25 14:59:24
【问题描述】:

正如 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 值为“1,2,3”。如果上述查询的输入参数值为 1,我可以检索此记录,但如果值为 2 或 3,则无法检索此记录。如何编写查询以检索包含特定项目的所有记录?

我的数据库是 MySQL。

【问题讨论】:

    标签: java mysql hibernate jpa-2.1


    【解决方案1】:

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

    但您始终可以自己构建该 SQL 片段,例如:

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

    第一个concat 是为了确保表达式匹配列表的第一个和最后一个值(不会以分隔符开始或结束)。

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

    另外备注:你不应该尝试在查询中加入userIds——因为它是基本类型,即使它是一个列表。参见@Convert的JavaDoc:

    Convert注解用于指定Basic字段的转换或 属性。

    尽管如此,如果您直接将属性与文字 (entity.userIds = '1') 进行比较,Hibernate 会报错,因为属性的类型与文字的类型不匹配。但是,只要您在比较的任一侧使用上述函数,它就不会抱怨。

    【讨论】:

    • 感谢您的解释和建议的解决方案。
    猜你喜欢
    • 1970-01-01
    • 2013-03-16
    • 1970-01-01
    • 2021-08-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-09
    • 1970-01-01
    相关资源
    最近更新 更多