我正在使用MySQL,并且有一个表具有与其他表中的ID相关的数据json数据,而不是具有中间表
当前有3个表:Customers,Assets和Table XXX,其中包含3列:id,name和myData。这是示例行:
1, "Some name",
[
{"customerId": 1, "assets": {"active": [10, 12, 13], "inactive": [15, 16]}}",
{"customerId": 2, "assets": {"active": [40, 42], "inactive": [19]}}"
]
顺便说一句,我无法更改设计:(
以下是实体:
@Table(name = "xxx")
class XXX {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "id")
private Long id;
private String name;
String myData;
}
@Table(name = "assets")
class Asset {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "id")
private Long id;
private String name;
}
@Table(name = "customers")
class Customer {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "id")
private Long id;
private String name;
}
但是,我希望实体XXX正确映射实体并具有客户和资产数据,类似于此:
@Table(name = "xxx")
class XXX {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "id")
private Long id;
private String name;
//maybe some awesome annotation here?
List<CustomerAssetsItem> customerAssetsItemsActive;
//maybe some awesome annotation here?
List<CustomerAssetsItem> customerAssetsItemsInactive;
}
CustomerAssetsItem如下所示:
class CustomerAssetsItem {
Customer customer;
List<Asset> assets;
}
使用JPA甚至有可能吗?还是应该只创建一个解析json字符串的新服务,运行我为构建层次结构而执行的所有查询? 谢谢!
答案 0 :(得分:0)
可能会看到以下示例:JSON Attribute converter
您所要做的就是提供一个AttributeConverter
,它将JSON字符串映射到您的列表或其他内容中。
在您的实体上,您必须通过@Converter
@Table(name = "xxx")
class XXX {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "id")
private Long id;
private String name;
@Converter(converter = CustomerAssetsConverter.class)
List<CustomerAssetsItem> customerAssetsItems;
}
您必须提供自己的转换器,这只是一个草稿。您需要添加一个JSON对象映射器。另外,如果您想在JSON中解析客户ID引用,则需要您自己的反序列化器,该序列化器针对customerId: 1
映射执行查询以获取该客户。请参见以下示例:Jackson Custom Deserializer
您可能不想解析引用,因为它们可能导致大量查询,而且您很可能需要调整很多设置以免陷入无限循环。
我建议启用二级缓存并适当使用@Transactional。
@Converter
public class CustomerAssetsConverter implements AttributeConverter<CustomerAssetsItem, String> {
//Add object mapper and repository
@Override
public String convertToDatabaseColumn(CustomerAssetsItem item) {
String itemJSON = null;
try {
itemJSON = objectMapper.writeValueAsString(item);
} catch (final JsonProcessingException e) {
}
return itemJSON;
}
@Override
public Map<String, Object> convertToEntityAttribute(String itemJSON) {
CustomerAssetsItem item = null;
try {
item = objectMapper.readValue(itemJSON, CustomerAssetsItem.class);
} catch (final IOException e) {
}
return item;
}
}