表示JPA中数据库表示和对象表示之间的差异

时间:2013-09-10 05:18:11

标签: java jpa eclipselink

我正在使用遗留数据库,该数据库经常使用以文本形式存储的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的新手,所以我很容易错过一些明显的东西。

非常感谢提前

3 个答案:

答案 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);
     }

}