spring-data-jdbc - 如何使用@Query 查询多列但不是所有列,但仍使用域数据模型与 Spring Data JDBC 进行映射?

标签 spring-data-jdbc

我的数据模型是

 @Getter
 @Setter
 public class Customer {
   @Id private ID id;
   @CreatedDate protected Instant createdAt;
   @LastModifiedDate protected Instant updatedAt;
   @CreatedBy protected String createdBy;
   @LastModifiedBy protected String updatedBy;
   @Version protected Long version;
   private UUID orderId;
   private String offer;
}

我的仓库是

public interface CustomerRepository extends CrudRepository<Customer, UUID> {

@Query(
        "SELECT ID, Offer  FROM Customer WHERE orderId = :orderId ")
List<Customer> findCustomerByOrderId(
        @Param("orderId") UUID orderId);
}

这将导致异常显示 'orderId column not found [42122-190]'。所以 Spring 希望您始终查询所有列。我知道使用 JPA,我们在实体和数据模式之间有一个强大的映射。但是 spring data JDBC 的重点是避免 POJO 的数据模型和数据库模式之间的紧耦合。为什么 EntityRowMapper 不只是将 NULL 映射到不属于查询的属性?

有没有办法告诉使用的 RowMapper 忽略不属于查询的属性?为这些简单的查询创建单独的 RowMapper 似乎有很多不必要的工作。

我仍然可以通过像

这样更改查询来解决这个问题
@Query(
        "SELECT ID, Offer, OrderId, null as CreatedAt, null as CreatedBy, null as UpdatedAt, null as UpdatedBy, null as Version  FROM Customer  WHERE orderId = :orderId ")

但这仍然会用空值序列化整个对象。我在这里遗漏了什么明显的东西吗?

注意 这不是 Spring Data JPA。它的 Spring Data JDBC。

编辑 仔细观察,异常来自 h2 数据库库。

Caused by: org.h2.jdbc.JdbcSQLException: Column "orderid" not found [42122-190]
at org.h2.message.DbException.getJdbcSQLException(DbException.java:345)
at org.h2.message.DbException.get(DbException.java:179)
at org.h2.message.DbException.get(DbException.java:155)
at org.h2.jdbc.JdbcResultSet.getColumnIndex(JdbcResultSet.java:3129)
at org.h2.jdbc.JdbcResultSet.get(JdbcResultSet.java:3217)
at org.h2.jdbc.JdbcResultSet.getObject(JdbcResultSet.java:522)
at com.zaxxer.hikari.pool.HikariProxyResultSet.getObject(HikariProxyResultSet.java)
at org.springframework.data.jdbc.core.EntityRowMapper.readFrom(EntityRowMapper.java:127)

最佳答案

你至少现在不能。

对此有三种解决方案,您已经指出了其中两种:

  1. 使用 , NULL as <column-name> 扩展您的选择语句对于所有缺失的列。

    我不确定

    But this will still serialize the entire object with null values.

意味着这在某些方面对您不起作用。

  1. 指定 RowMapper .
  2. 您可以使用一个包含查询返回字段的类。如果您想要一个由您的普通实体和部分实体实现的接口(interface),它甚至可以为其他列提供 getter。

你写:

But the whole point of spring data JDBC is to avoid the tight coupling between pojo's data model and database schema.

这不太对。 Spring Data JDBC 的一个重要目标是在实体和表行之间不存在运行时连接。 这将需要代理或类似的东西,并带来很多复杂性。 但是实体和表之间的结构映射可能会更强大(现在肯定是这样),因为 JPA 中可用的所有映射变体都带来了复杂性。 Spring Data JDBC 的主要目标是在概念上比 JPA 更简单。

你也问

Why not the EntityRowMapper is just mapping NULL to the properties which are not part of the query?

我不确定我在编码时是否积极考虑过它,但我不喜欢默认为 NULL 的想法。因为这很容易因为别名中的拼写错误而导致意外不加载列。

但我并不反对替代解决方案。 如果你有想法please create a feature request .

关于spring-data-jdbc - 如何使用@Query 查询多列但不是所有列,但仍使用域数据模型与 Spring Data JDBC 进行映射?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55146977/

相关文章:

java - Spring Data JDBC - POJO 中的 Clob 列到 String 属性不起作用

java - 为什么 Spring-data-jdbc 不保存我的 Car 对象?

java - spring-data-jdbc deleteBy<field> 方法返回异常结果类型

无法识别Spring Data JDBC Firebird方言

java - 如何在 Spring Data JDBC 中获取对象属性到表字段名称的映射?

java - 具有多个相同类型值对象的聚合根问题

java - 使用手动 PK(不是自动生成的)使用 Spring 数据 JDBC CrudRepository 插入 oracle

spring - 使用 Spring Data JDBC 和 CrudRepository 接口(interface)的多个数据源

mysql - 将枚举列表保存到MySql时,Spring Data JDBC SQLFeatureNotSupportedException