在 Spring 数据 JDBC 中使用 @Id 注释的复合实体有什么影响?

What's the impact of having an @Id annotated composite entity in Spring Data JDBC?

我的 Spring 数据 JDBC 项目中有一个复合实体 class,可以映射到 table item

虽然字段 idcodeitemName 来自 table item,但字段 groupName 属于另一个 table, item_group.

我通过使用存储库中的自定义查询成功加载了这个实体对象,如下所示:

"SELECT a.id, a.code, a.name AS item_name, b.name as group_name from item a LEFT JOIN item_group b ON a.group_id = b.id where a.id=:id")

像这样 @Id 注释复合 class 有什么影响吗?

public class Item 
{
    @Id
    private long id;
    private String code;
    private String itemName;
    private String groupName;
    
    public long getId() {
        return id;
    }
    public void setId(long id) {
        this.id = id;
    }
    public String getCode() {
        return code;
    }
    public void setCode(String code) {
        this.code = code;
    }
    public String getItemName() {
        return itemName;
    }
    public void setItemName(String itemName) {
        this.itemName = itemName;
    }
    public String getGroupName() {
        return groupName;
    }
    public void setGroupName(String groupName) {
        this.groupName = groupName;
    }

乍一看这确实不对。

您将无法加载,更不用说使用标准 CRUD 方法保存它了。

它看起来也不对,因为看起来您正在合并两个聚合:ItemGroup,它们实际上应该是单独的聚合,它们之间没有 Java 引用。参见 Spring Data JDBC, References, and Aggregates

但如果您将其视为专门上下文的视图,它确实有意义。 如果你只需要它来从数据库中读取它是一种非常有效的方法。它简单高效,因为它将所有必需的数据加载到一个 select.

假设这是你所处的情况,我会推荐以下内容:

  1. 在数据库中为连接创建一个视图。否则联接将在每个查询中一遍又一遍地重复。
  2. 如果您有这样的视图,您实际上可以删除 @Query 注释并仅使用标准 find... 方法。
  3. 不要让您的存储库扩展 CrudRepository 而只是 Repository 并仅手动添加您实际需要的方法。这避免了混淆,并明确表示此存储库和实体只能用于阅读。
  4. 如果您使用标准 find... 方法,您必须有一个正确注释的 ID 属性。如果您不使用 find... 方法,则 @Id 注释是多余的。