Oracle Hibernate查询比较逗号分隔字符串与列表 问题

Oracle Hibernate查询比较逗号分隔字符串与列表 问题,oracle,hibernate,spring-boot,spring-data-jpa,hql,Oracle,Hibernate,Spring Boot,Spring Data Jpa,Hql,我正在开发一个spring引导应用程序,它需要从oracle数据库读取数据。 数据库本身不在我的控制范围之内,我无法改变它的结构方式。 我将SpringDataJPA与hibernate结合使用来与数据库交互。 我拥有以下实体: @Entity @Table(name = "mytable") public class MyEntity { @Id @Column private String entityId; // This column might hav

我正在开发一个spring引导应用程序,它需要从oracle数据库读取数据。 数据库本身不在我的控制范围之内,我无法改变它的结构方式。 我将SpringDataJPA与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;
}
列AssociatedID包含逗号分隔的值,例如abc、xyz、a1b。 “我的应用程序”的用户只有权读取至少有1个其有权访问的associatedId的行。他们有权访问的ID表示为允许ID的列表

为了确保用户只接收他们被允许接收的数据,我需要限制我的查询。我在构造符合我的要求的查询时遇到问题。 如果用户只能访问单个Id,我可以使用简单的LIKE运算符使用以下查询:

@Query(value = "SELECT e FROM MyEntity e WHERE e.associatedIds LIKE '%:allowedId%'")
Page<MyEntity> findAllByAllowedId(@Param("allowedId") String allowedId, Pageable pageable);
这种转换是有效的,但不允许我像列是列表一样构造查询,因为数据库保持不变

方法3:@公式 另一种可能的解决方案可能是hibernate的@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..
使用这种方法,我也不知道如何在SpringDataJPA中实现它


对于如何实施这些解决方案或我没有想到的建议,我将不胜感激。

如何使用正则表达式函数regexp\u substr:


使用正则表达式函数regexp\u substr怎么样:


测试该解决方案后,它似乎会将列AssociatedID与参数AllowedId中的每个条目进行比较。问题是,列AssociatedID本身是一个以逗号分隔的ID列表。我无法在AssociatedID中找到任何具有多个ID的行。很难理解您的意思。你能用简单的话解释一下吗我要搜索的数据库列包含abc等值或abc、xyz、lmn等值。在我的java代码中,我有一个值列表,例如[abc、aaa、qqq]。我想从java代码中获取数据库列中至少包含一个值的每一行。例如,如果我输入[abc,bbb],行abc,ccc应该匹配。如果我输入[xyz,ccc],它也应该返回。您可以通过将列表转换为字符串来解决问题吗?假设您有一个列表,如listOfIds String allowedId=StringUtils.joinlistOfIds,,;在上面的查询中使用它。我完全可以这样做,这就是我在测试select语句时所做的。我首先比较了db列ccc和abc列ccc,它确实匹配。但是,当我比较db列abc、ccc和abc、bbb时,它并不匹配。我认为它最终将abc与整个abc、ccc进行了比较,然后将bbb与abc、ccc进行了比较。在测试该解决方案之后,它似乎将列AssociatedID与参数AllowedId中的每个条目进行了比较。问题是,列AssociatedID本身是一个以逗号分隔的ID列表。我无法在AssociatedID中找到任何具有多个ID的行。很难理解您的意思。你能用简单的话解释一下吗我要搜索的数据库列包含abc等值或abc、xyz、lmn等值。在我的java代码中,我有一个值列表,例如[abc、aaa、qqq]。我想从java代码中获取数据库列中至少包含一个值的每一行。例如,如果我输入[abc,bbb],行abc,ccc应该匹配。如果我输入[xyz,ccc],它也应该返回。您可以通过将列表转换为字符串来解决问题吗?假设您有一个列表,如listOfIds String allowedId=StringUtils.joinlistOfIds,,;在上面的查询中使用它。我完全可以这样做,这就是我在测试select语句时所做的。我首先比较了db列ccc和abc列ccc,它确实匹配。但是,当我比较db列abc、ccc和abc、bbb时,它并不匹配。我认为它最终比较了abc和整个abc,ccc,然后bbb和abc,ccc。
@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(","));
    }
}
SELECT e FROM MyEntity e WHERE e.allowedIds LIKE'%allowedIds.get(0)%' OR e.allowedIds LIKE'%allowedIds.get(1)%' etc..
@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);