0

我正在使用一个遗留数据库,该数据库经常使用存储为文本的 JSON 块。我正在尝试编写一些 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);
     }

}

在这里,表示在数据库和对象中总是作为 JSON 字符串,虽然它可以工作(到目前为止),但它的效率非常低,因为每次修改对象的状态时都必须解析 JSON。我很感激我可以通过在内存中缓存 Stuff 对象来提高当前解决方案的性能,但是我仍然必须在每次调用 setter 时将它们序列化为 JSON,并确保状态的 2 表示(对象和 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 上有效。我可以实现上述目标 - 在对象中使用一种表示形式,在数据库中使用不同的表示形式吗?我是 JPA 的新手,所以我很容易遗漏一些明显的东西。

提前谢谢了

4

3 回答 3

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);
     }
}
于 2013-09-10T05:22:43.903 回答
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){
             ....
         }
     }
}
于 2013-09-10T05:36:32.993 回答
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);
     }

}
于 2013-09-10T05:49:52.750 回答