我有数据类/表“用户”,其中包含“首选项”
CREATE table "user";
ALTER TABLE "user" ADD COLUMN preferences TEXT;
首选项类型是TEXT,我在那里存储JSON。
public class User extends AbstractEntity{
public String preferences;
}
因此user.preferences
值为"{notifyByEmail:1, favouriteColor:"blue" }"
如何用一些注释包装它,以便我可以像
一样访问它user.preferences.notifyByEmail
或者无需包装到数据对象
user.preferences.get("notifByEmail");
user.preferences.set("notifByEmail",true);
我想可能会有一些杰克逊注释可以添加到字段中 像
@JsonGenerate
public String preferences;
我对JPA相当新,文档很陡。
我相信我的情况很常见。任何人都可以提供任何例子吗?
答案 0 :(得分:11)
可以使用JPA Converter实现此目的。
实体;
Toolbar toolbar = (Toolbar) findViewById(R.id. toolbar_target_ranges);
LinearLayout toolbarRow = (LinearLayout) toolbar.findViewById(R.id. target_ranges_layout_main);
toolbarRow.setLayoutParams(new Toolbar.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT, Gravity.CENTER));
转换器:
@Id
@GeneratedValue
Long id;
@Column(name = "mapvalue")
@Convert(converter = MapToStringConverter.class)
Map<String, String> mapValue;
保存数据:
@Converter
public class MapToStringConverter implements AttributeConverter<Map<String, String>, String> {
ObjectMapper mapper = new ObjectMapper();
@Override
public String convertToDatabaseColumn(Map<String, String> data) {
String value = "";
try {
value = mapper.writeValueAsString(data);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
return value;
}
@Override
public Map<String, String> convertToEntityAttribute(String data) {
Map<String, String> mapValue = new HashMap<String, String>();
TypeReference<HashMap<String, Object>> typeRef = new TypeReference<HashMap<String, Object>>() {
};
try {
mapValue = mapper.readValue(data, typeRef);
} catch (IOException e) {
e.printStackTrace();
}
return mapValue;
}
}
该值将作为
存储在DB中Map<String, String> mapValue = new HashMap<String, String>();
mapValue.put("1", "one");
mapValue.put("2", "two");
DataEntity entity = new DataEntity();
entity.setMapValue(mapValue);
repo.save(entity);
答案 1 :(得分:5)
老实说,我认为您最好的解决方案是为您的房产创建一个单独的表格(首选项)。
+------------+
| preference |
+------------+---------+------+-----+
| Field | Type | Null | Key |
+------------+---------+------+-----+
| user_id | bigint | NO | PRI |
| key | varchar | NO | PRI |
| value | varchar | NO | |
+------------+---------+------+-----+
您可以在您的实体中将其映射到这样:
@Entity
public class User
{
@Id
private Long id;
@ElementCollection
@MapKeyColumn(name = "key")
@Column(name = "value")
@CollectionTable(name = "preference",
joinColumns = @JoinColumn(name = "user_id"))
private Map<String, String> preferences;
}
通过这种方式,您的数据库更加规范化,您不必愚弄“创造性解决方案”,例如将首选项存储为JSON。
答案 2 :(得分:2)
如果你真的需要这样的东西,最值得推荐的是下一个:
public class User extends AbstractEntity{
@JsonIgnore //This variable is going to be ignored whenever you send data to a client(ie. web browser)
private String preferences;
@Transient //This property is going to be ignored whenever you send data to the database
@JsonProperty("preferences") //Whenever this property is serialized to the client, it is going to be named "perferences" instead "preferencesObj"
private Preferences preferencesObj;
public String getPreferences() {
return new ObjectMapper().writeValueAsString(preferencesObj);
}
pbulic void setPreferneces(String preferences) {
this.preferences = preferences;
this.preferncesObj = new ObjectMapper().readValue(preferences, Preferences.class);
}
pubilc Preferences getPreferencesObj() {
return preferencesObj;
}
public void setPreferencesObj(Preferences preferencesObj) {
this.preferencesObj = preferencesObj;
}
}
附加说明:
答案 3 :(得分:1)
正如我在this article中所解释的那样,使用Hibernate持久化JSON对象非常容易。
您不必手动创建所有这些类型,您可以简单地获取 它们通过Maven Central使用以下依赖项:
<dependency> <groupId>com.vladmihalcea</groupId> <artifactId>hibernate-types-52</artifactId> <version>${hibernate-types.version}</version> </dependency>
有关详细信息,请查看hibernate-types open-source project。
现在,您需要在类级别或 package-info.java 包级别描述符中声明新类型:
@TypeDef(
name = "jsonb-node",
typeClass = JsonNodeBinaryType.class
)
实体映射将如下所示:
@Type(type = "json-node")
@Column(columnDefinition = "json")
private JsonNode preferences;
那就是它!