Hibernate查询将逗号分隔的字符串与列表进行比较

问题描述 投票:0回答:1

问题

我正在开发一个需要从oracle数据库读取数据的spring-boot应用程序。数据库本身不在我的控制范围之内,我无法更改其结构方式。我将结合使用spring-data-jpa和hibernate与数据库进行交互。我有以下实体:

@Entity
@Table(name = "mytable")
public class MyEntity {
    @Id
    @Column
    private String entityId;

    // This column might have a value like "abc,xyz,a1b" in the db
    @Column
    private String associatedIds;
}

associatedIds列包含逗号分隔的值(例如abc,xyz,a1b)。我的应用程序的用户仅有权读取他们有权访问的至少为1 associatedId的行。他们可以访问的ID表示为List<String> allowedIds

为了确保用户仅接收他们允许的数据,我需要限制查询。我在构建满足我要求的查询时遇到了麻烦。如果用户只能访问一个ID,我可以使用简单的LIKE运算符简单地使用以下查询:

@Query(value = "SELECT e FROM MyEntity e WHERE e.associatedIds LIKE '%:allowedId%'")
Page<MyEntity> findAllByAllowedId(@Param("allowedId") String allowedId, Pageable pageable);

该查询不足以满足我的用例,因为用户可以访问多个ID。

我想出了几种方法来解决此问题,但没有设法完全实现其中的任何一种。

方法1:“喜欢”

第一种方法是这样的查询:

@Query(value = "SELECT e FROM MyEntity e WHERE e.associatedIds IN (LIKE '%:allowedIds%')")
Page<MyEntity> findAllByAllowedIds(@Param("allowedIds") List<String> allowedIds, Pageable pageable);

这不起作用,因为据我所知,没有查询将INLIKE组合在一起。

方法2:“ AttributeConverter”

我想做的下一件事是使用以下转换器将逗号分隔的字符串转换为List<String>

@Converter
public class StringArrayToStringConverter implements AttributeConverter<List<String>, String> {
    @Override
    public String convertToDatabaseColumn(List<String> strings) {
        return strings == null ? null : StringUtils.join(strings, ',');
    }

    @Override
    public List<String> convertToEntityAttribute(String s) {
        if(StringUtils.isBlank(s)) {
            return Collections.emptyList();
        }
        return Arrays.asList(s.split(","));
    }
}

此转换有效,但由于数据库保持不变,因此不允许我像列是列表那样构造查询。

方法3:“ @ Formula”

[另一个可能的解决方案可能是休眠的@Formula注释。可能有一种方法可以创建一个虚拟列,可以根据我的要求进行搜索。但是我不知道从哪里开始,因为我以前从未使用过该注释,也不太了解oracle中列表类型的工作方式。要考虑的另一件事是您是否可以实际上对公式列执行hql查询。

方法4:“多个OR”

我想出的最后一个可能的解决方案是为每个允许的ID添加一个单独的where子句,结果可能看起来像这样:

SELECT e FROM MyEntity e WHERE e.allowedIds LIKE'%allowedIds.get(0)%' OR e.allowedIds LIKE'%allowedIds.get(1)%' etc..

使用这种方法,我也不知道如何在spring-data-jpa中实现它。

我将非常感谢一些有关如何实施这些解决方案或我没有想到的建议的指导。

oracle hibernate spring-boot spring-data-jpa hql
1个回答
0
投票

如何使用正则表达式函数regexp_substr

@Query(value = "SELECT e FROM MyEntity e WHERE e.associatedIds IN ( SELECT regexp_substr(:allowedId,'[^,]+', 1, level) FROM dual connect by regexp_substr(:allowedId, '[^,]+', 1, level) IS NOT NULL \n#pageable\n" ,nativeQuery=true )
Page<MyEntity> findAllByAllowedId(@Param("allowedId") String allowedId, Pageable pageable);
© www.soinside.com 2019 - 2024. All rights reserved.