问题描述
在我的Spring Data JDBC项目中,我有一个如下所示的复合实体类,可以将其映射到表item
。
字段id
,code
和itemName
来自表item
,而字段groupName
属于另一个表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
注释的复合类是否有影响?
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方法保存它了。
它看起来也不对,因为您似乎正在合并两个聚合:Item
和Group
,它们实际上应该是单独的聚合,它们之间没有Java引用。参见Spring Data JDBC,References,and Aggregates
但是,如果您认为它是针对特定上下文的视图,则确实有意义。 如果只需要它来从数据库中读取,则这是一种非常有效的方法。它简单高效,因为它一次选择即可加载所有必需的数据。
假设这是您所处的情况,我将建议以下内容:
- 在数据库中为联接创建一个视图。否则,该联接将在每个查询中一遍又一遍地重复。
- 如果您有这样的视图,则实际上可以删除
@Query
批注,而仅使用标准的find...
方法。 - 不要让您的存储库扩展
CrudRepository
,而只能扩展Repository
并仅手动添加您实际需要的方法。这样可以避免混淆,并且很明显,该存储库及其实体只能用于读取。 - 如果您使用标准的
find...
方法,则必须具有正确注释的id属性。如果您不使用find...
方法,则@Id
注释是多余的。