【问题标题】:Spring Data R2DBC - Building custom postgresql query in reactive repositorySpring Data R2DBC - 在反应式存储库中构建自定义 postgresql 查询
【发布时间】:2019-10-02 17:54:34
【问题描述】:

我有一个表,其中包含具有字符串 id、字符串 jobId 和字符串状态的实体。给定一个 jobId 和一个 ID 列表,我想查询该表并返回数据库中不存在的 ID 的 Flux。

如果我在 pgadmin 中手动执行以下查询,我可以成功地做到这一点:

SELECT a.id FROM (VALUES ('20191001_182447_1038'),('abc'),('fdjk')) AS a(id) LEFT JOIN (SELECT * FROM items WHERE job_id = '10a7a04a-aa67-499a-83eb-0cd3625fe27a') b ON a.id = b.id WHERE b.id IS null

返回的响应仅包含不存在的 id,“abc”和“fdjk”。

在我的 spring 数据仓库中,我定义了以下方法:

    @Query("SELECT a.id FROM (VALUES (:ids)) AS a(id) LEFT JOIN (SELECT * FROM items WHERE job_id = :jobId) b ON a.id = b.id WHERE b.id IS null")
    Flux<ItemId> getNotContains(@Param("jobId") String jobId, @Param("ids") Collection<String> ids);

问题是,当我运行代码时,查询被扩展为:

SELECT a.id FROM (VALUES ($1, $2, $3)) AS a(id) LEFT JOIN (SELECT * FROM items WHERE job_id = $251) b ON a.id = b.id WHERE b.id IS null]

这总是返回一个值,因为这些值被分组到一组括号中,而不是将我集合中的每个元素都包装在括号中。只是好奇是否有办法妥善处理。

编辑 实体类是:

@Data
@Table("items")
public class Item implements Persistable {

    @Id
    private String id;
    private String jobId;
    private String customerId;
    private Date queuedDate;
    private Date lastUpdated;
    private String destination;
    private String type;
    private Status status;
}

另外,我的仓库是:

public interface ItemRepository extends R2dbcRepository<Item, String>

R2dbcRepository 目前不支持更成熟的 spring 数据仓库的神奇魔力,所以你不能像 findByJobId 那样让它为你自动生成查询。

【问题讨论】:

  • 而不是(:ids),只需在@Query 中使用:ids。你能分享你的实体类吗?可能有一种方法可以不用@Query
  • 你试过这个findByJobIdAndItemIdNotIn(@Param("jobId") String jobId, @Param("ids") List&lt;String&gt; ids)吗?
  • 感谢@pvpkiran - 从 :ids 中删除括号是解决方案的一部分!

标签: spring spring-data-jpa spring-data spring-el spring-data-r2dbc


【解决方案1】:

您可以通过将参数包装到 Object[] 中来强制使用括号,以将参数呈现为表达式列表。

interface MyRepo {
    @Query(…)
    Flux<ItemId> getNotContains(@Param("jobId") String jobId, @Param("ids") Collection<Object[]> ids);
}

MyRepo myRepo = …;
Collection<Object[]> ids = Arrays.asList(new Object[]{"1"}, new Object[]{"2"});

myRepo.getNotContains("foo", ids);

另见:

【讨论】:

  • 谢谢!我知道看到它在每个值周围都用括号扩展,这样我就更接近了,但是现在它返回 0 个结果。我也用 String[] 而不是 Object[] 尝试过——不走运。有没有办法查看正在执行的 actual 语句,并在语句中填充了实际值?将 org.springframework.data 和 io.r2dbc 设置为 DEBUG 似乎仍然没有显示出来。
  • 使用 Spring Data (org.springfrsmework.data) 的日志分类
  • 在我还实施了@pvpkiran 的建议以从 :ids 中删除括号后,这最终奏效了
猜你喜欢
  • 2016-08-29
  • 1970-01-01
  • 2021-04-01
  • 1970-01-01
  • 2021-10-10
  • 2018-10-06
  • 2017-09-19
  • 1970-01-01
  • 2017-11-15
相关资源
最近更新 更多