Spring Data和Cassandra @Query中的IN子句

11

我正在尝试使用Spring Data中的@Query注释和IN子句查询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') 结束。


1
你尝试过任何集合类型吗?使用字符串集合(Set)或列表(List)代替字符串数组(String array)了吗? - Mustafa Genç
列表和集合在启动时都会返回类似于以下错误:Caused by: java.lang.IllegalArgumentException: 遇到不支持的查询参数类型 [interface java.util.Set] - Bill H
3个回答

11

更新

目前的情况下,似乎在使用IN时不需要使用括号。


旧答案

当您使用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个参数,所以最终出现了“无效的绑定变量数量”异常。当我传递单个字符串进行约束时,我可以使其正常工作,但是当我传递数组时,在启动时会看到以下错误信息: Caused by: java.lang.IllegalArgumentException: encountered unsupported query parameter type [class [Ljava.lang.String;] - Bill H
1
那么你可以尝试第一个。使用括号的相同查询。像 IN (?1) - Faraj Farook
如果我传递一个单一的名称,它可以工作。但是如果我传递多个名称,则会被包含在引号中,因此查询结果为IN('Joe,Jim')。显然,没有人叫做'Joe,Jim'。我还尝试构建请求字符串'Joe','Jim',但当它被传递到库中时,所有引号都被转义了,最终我得到了'''Joe'',''Jim''' - Bill H
4
如果没有大括号,使用当前版本的Spring Cassandra,它可以正常工作。public List findByLastName(String lastName, List firstName); ``` - Nitish Bhagat
使用List集合,这对我起作用了。 - Jayyrus
显示剩余2条评论

3
尼提什·巴加特是正确的,使用当前版本spring-data-cassandra:2.0.6.RELEASE时,它不支持花括号。
对于我来说,它仅在没有花括号的情况下工作,如下所示: @Query("SELECT * FROM people WHERE first_name IN ?0") public List<People> findByFirstName(List<String> firstName);

那么,你把一条评论变成了自己的答案? - Abhijit Sarkar

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和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 异常。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接