带有 Spring Data 和 Cassandra @Query 的 IN 子句

Posted

技术标签:

【中文标题】带有 Spring Data 和 Cassandra @Query 的 IN 子句【英文标题】:IN clause with Spring Data and Cassandra @Query 【发布时间】:2015-06-07 17:03:10 【问题描述】:

我正在尝试使用 IN 子句和 Spring Data 中的 @Query 注释来查询 Cassandra 表。我有一个分区键为 last_name 和集群键为 first_name 的表。

我有这个查询工作

@Query("SELECT * FROM people WHERE last_name=?0")
public List<People> findByLastName(String lastName);

我想做类似的事情

@Query("SELECT * FROM people WHERE last_name=?0 AND first_name IN ?1")
public List<People> findByLastName(String lastName, String[] firstName);

我已经使用它了

CassandraOperations.select("SELECT * FROM people WHERE last_name=" + lastName + 
" AND first_name IN (" + concatinatedNameList + ")", People.class);

但出于多种原因(代码风格、测试,我发誓还有更多)我更喜欢使用@Query。有什么想法吗?

编辑以获取更多信息!

传入数组、集合或列表返回Caused by: java.lang.IllegalArgumentException: encountered unsupported query parameter type [class [Ljava.lang.String;] in method public abstract

也试过了:

String firstName = "Joe,Jim";
@Query("SELECT * FROM people WHERE last_name=?0 AND first_name IN (?1)")
public List<People> findByLastName(String lastName, String firstName);

没有找到,图书馆搜索一个连名('Joe,Jim')的人

String firstName = "'Joe','Jim'";
@Query("SELECT * FROM people WHERE last_name=?0 AND first_name IN (?1)")
public List<People> findByLastName(String lastName, String firstName);

没有找到,请求被转义并结束('''Joe'',''Jim''')

String firstName = "Joe','Jim"; // Hoping the library would just add the outer quotes, getting desperate
@Query("SELECT * FROM people WHERE last_name=?0 AND first_name IN (?1)")
public List<People> findByLastName(String lastName, String firstName);

没有找到,请求被转义并结束('Joe'',''Jim')

【问题讨论】:

您尝试过任何 Collection 类型吗?设置或字符串列表而不是字符串数组? Lists 和 Sets 在启动时都会返回类似的错误Caused by: java.lang.IllegalArgumentException: encountered unsupported query parameter type [interface java.util.Set] 【参考方案1】:

更新

使用当前的弹簧,它似乎可以在没有大括号的情况下工作。


旧答案

使用IN 时必须使用护腕。

@Query("SELECT * FROM people WHERE last_name=?0 AND first_name IN (?1)")
public List<People> findByLastName(String lastName, String[] firstName);

但是您的代码中还有一些其他问题。我将它们全部更改为良好的编码标准,如下所示。包括我个人最喜欢使用命名参数。

@Query("SELECT p FROM People p WHERE p.lastName = :lastName AND p.firstName IN (:firstNames)")
public List<People> findByName(@Param("lastName") String lastName, @Param("firstNames") String[] firstNames);

【讨论】:

我希望我可以使用命名参数,但由于我实际上是传入 7,所以我最终得到了 Invalid amount of bind variable 异常。传入单个字符串以进行约束时,我能够使其正常工作,但是当传入数组时,我在启动时看到了这一点 Caused by: java.lang.IllegalArgumentException: encountered unsupported query parameter type [class [Ljava.lang.String;] 那你可以试试第一个。带括号的相同查询。喜欢IN (?1) 如果我传入一个名字,它确实有效。如果我传递多个,它会被包裹在引号中,因此查询以IN ('Joe,Jim') 结尾。显然,没有人被命名为“乔,吉姆”。我还尝试构建一个请求字符串'Joe','Jim',但是当它在库中传递时会转义所有引号,我最终得到'''Joe'',''Jim''' 我想这些查询在接口中所以你不需要公共修饰符 使用当前的 Spring Cassandra,如果你没有大括号,它就可以工作。@Query("SELECT * FROM people WHERE last_name=?0 AND first_name IN ?1") public List&lt;People&gt; findByLastName(String lastName, List&lt;String&gt; firstName); 【参考方案2】:

这似乎是不可能的!

我查看了spring-data-cassandra-1.3.2.RELEASE.jar的源代码。

查询方法中参数允许的数据类型有 String.class, CharSequence.class, char.class, Character.class, char[].class, long.class, Long.class, boolean.class, Boolean.class, BigDecimal.class, BigInteger.class, double.class, Double.class, float.class, Float.class, InetAddress.class, Date.class, UUID.class, int.class are Integer.class

它们可以在

中找到
org.springframework.data.cassandra.repository.query.CassandraQueryMethod.ALLOWED_PARAMETER_TYPES = Collections.unmodifiableList(Arrays
            .asList(new Class<?>[]  String.class, CharSequence.class, char.class, Character.class, char[].class, long.class,
                    Long.class, boolean.class, Boolean.class, BigDecimal.class, BigInteger.class, double.class, Double.class,
                    float.class, Float.class, InetAddress.class, Date.class, UUID.class, int.class, Integer.class ));

如果我们传递的数据类型不是这些,那么org.springframework.data.cassandra.repository.query.CassandraQueryMethod.verify(Method method, RepositoryMetadata metadata) 将抛出IllegalArgumentException

【讨论】:

【参考方案3】:

Nitish Bhagat 是对的,使用当前版本 spring-data-cassandra:2.0.6.RELEASE 它确实与大括号一起工作。

对我来说,它只适用于没有大括号,例如: @Query("SELECT * FROM people WHERE first_name IN ?0") public List<People> findByFirstName(List<String> firstName);

【讨论】:

那么,您发表了评论并做出了自己的回答?

以上是关于带有 Spring Data 和 Cassandra @Query 的 IN 子句的主要内容,如果未能解决你的问题,请参考以下文章

扩展 AbstractCassandraConfiguration 忽略 application.yml 自动配置

带有嵌套字段和映射的 Spring Data 弹性搜索

带有 H2 和 data.sql 的 Spring Boot Data JPA - 未找到表

带有 Spring Data 和 Cassandra @Query 的 IN 子句

带有 Spring Data 的 Spring Boot Maven 多模块项目

Hibernate 和 Spring Data JPA 无法处理带有特殊字符的 Oracle 表名?