我正在使用遗留数据库,该数据库经常使用以文本形式存储的JSON blob。我正在尝试编写一些JPA类,它们将隐藏此实现细节,使其更容易使用数据库,并允许我们将来重构数据库模式。我目前的做法是:
class MyTableObject{
@Lob
@Column(name = "stuff")
private String jsonString;
public List<Stuff> getStuff(){
return jsonToStuff(jsonString);
}
public setStuff(List<Stuff> stuff){
jsonString = stuffToJsonString(stuff);
}
}
这里,表示总是作为数据库和Object中的JSON字符串,虽然它可以工作(到目前为止),但由于每次修改对象的状态时都必须解析JSON,因此效率很低。 。我感谢我可以通过在内存中缓存Stuff对象来提高当前解决方案的性能,但是每次调用setter时我仍然必须将它们序列化为JSON,并确保状态的两个表示(Objects和JSON)是始终同步。我希望能够做的是告诉框架在进出的路上转换我的字段,如:
class MyTableObject{
private List<Stuff> stuff;
@Lob
@Column(name = "stuff")
public String getStuffAsJsonString(){
return stuffToJsonString(stuff);
}
@Column(name = "stuff")
public setStuffFromJsonString(String jsonString){
stuff = stuffFromJsonString(jsonString);
}
}
但是,据我所知,注释仅在getter上有效。我可以实现类似上面的内容 - 在Object中有一个表示形式,在数据库中有不同的表示形式吗?我是JPA的新手,所以我很容易错过一些明显的东西。
非常感谢提前
答案 0 :(得分:0)
注释仅在getter上有效 。单个注释可以处理getter和setter:你不需要加倍注释。
所以,你基本上已经弄明白了。移除设置器上的额外@Column(name = "stuff")
即可离开比赛。
class MyTableObject {
private List<Stuff> stuff;
@Lob
@Column(name = "stuff")
public String getStuffAsJsonString(){
return stuffToJsonString(stuff);
}
public setStuffFromJsonString(String jsonString){
stuff = stuffFromJsonString(jsonString);
}
}
答案 1 :(得分:0)
您可以注释getter。当从数据库加载对象时,JPA将使用相应的setter。
我会使用仅用于JPA的受保护属性和用于客户端的公共访问者。 公共访问器在需要时将json字符串转换为填充列表。
以同样的方式,JPA的属性访问器方法将东西列表转换为json字符串(如果需要)。
class MyTableObject {
private String jsonStuff;
private List<Stuff> stuff;
@Lob
@Column(name = "stuff")
protected String getJsonStuff(){
if(jsonStuff == null){
jsonStuff = stuffToJsonString(stuff);
}
return jsonStuff;
}
protected void setJsonStuff(String jsonString){
if(jsonString != null && jsonString.equals(this.jsonStuff)){
// the new string is equal to the old one. No need to re-convert.
return;
}
this.jsonStuff = jsonString;
// jsonStuff changed we have to re-convert json to list
// thus we set stuff to null
stuff = null;
}
public List<Stuff> getStuff(){
if(stuff == null){
stuff = stuffFromJsonString(jsonStuff);
}
return Collections.unmodifiableList(stuff);
}
public void setStuff(List<String> stuff){
if(suffListNotChanged(stuff)){
// the new stuff list is equal to the old one. No need to rebuild json.
return;
}
this.stuff = new ArrayList<String>(stuff);
// the stuff list changed
// thus the jsonStuff string must be rebuild
this.jsonStuff = null;
}
private boolean suffListNotChanged(List<Stuff> stuffList){
...
}
private String stuffToJsonString(List<Stuff> stuffList){
if(stuffList == null){
....
}
}
private List<Stuff> stuffFromJsonString(String stuff){
if(stuff == null){
....
}
}
}
答案 2 :(得分:0)
您甚至不必担心应该注释哪个getter / setter。以下代码应全部设置:
class MyTableObject{
@Lob
@Column(name = "stuff")
private List<Stuff> stuffAsJsonString;
public String getStuffAsJsonString(){
return stuffToJsonString(stuff);
}
public setStuffFromJsonString(String jsonString){
stuff = stuffFromJsonString(jsonString);
}
}