Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/jpa/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 在JPA中表示数据库表示和对象表示之间的差异_Java_Jpa_Eclipselink - Fatal编程技术网

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

Java 在JPA中表示数据库表示和对象表示之间的差异,java,jpa,eclipselink,Java,Jpa,Eclipselink,我正在使用一个遗留数据库,该数据库经常使用存储为文本的JSON块。我正在尝试编写一些JPA类,这些类将隐藏这个实现细节,使使用数据库更容易,并允许我们在将来重构数据库模式。我目前的做法是: class MyTableObject{ @Lob @Column(name = "stuff") private String jsonString; public List<Stuff> getStuff(){ return jso

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

}
类MyTableObject{
@高球
@列(name=“stuff”)
私有字符串jsonString;
公共列表getStuff(){
返回jsontoff(jsonString);
}
公共设置凝灰岩(列表材料){
jsonString=stuffToJsonString(stuff);
}
}
在这里,表示在数据库和对象中始终是JSON字符串,尽管它可以工作(到目前为止),但效率非常低,因为每次修改对象的状态时都必须解析JSON。我很感激我可以通过在内存中缓存Stuff对象来提高当前解决方案的性能,但我仍然必须在每次调用setter时将它们序列化为JSON,并确保状态的两种表示(对象和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);
     }

}
类MyTableObject{
私人物品清单;
@高球
@列(name=“stuff”)
公共字符串getStuffAsJsonString(){
将stuff返回到JSonString(stuff);
}
@列(name=“stuff”)
公共setStuffFromJsonString(字符串jsonString){
stuff=stuffFromJsonString(jsonString);
}
}
然而,据我所知,注释仅在getter上有效。我可以通过在对象中使用一种表示,在数据库中使用另一种表示来实现上述功能吗?我是JPA新手,所以我很容易错过一些明显的东西

提前非常感谢

注释并不是只在getter上有效。单个注释负责getter和setter:您不需要双重注释

所以,你基本上已经明白了。删除setter上额外的
@列(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);
     }
}
类MyTableObject{
私人物品清单;
@高球
@列(name=“stuff”)
公共字符串getStuffAsJsonString(){
将stuff返回到JSonString(stuff);
}
公共setStuffFromJsonString(字符串jsonString){
stuff=stuffFromJsonString(jsonString);
}
}

您可以只注释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){
             ....
         }
     }
}
类MyTableObject{
私有字符串JSONSTAFF;
私人物品清单;
@高球
@列(name=“stuff”)
受保护的字符串getjsonstaff(){
if(jsonstaff==null){
jsonstaff=stuffToJsonString(stuff);
}
返回JSONSTAFF;
}
受保护的void setJsonStuff(字符串jsonString){
if(jsonString!=null&&jsonString.equals(this.jsonStuff)){
//新字符串等于旧字符串。无需重新转换。
返回;
}
this.jsonStuff=jsonString;
//JSONSTAFF已更改我们必须将json重新转换为列表
//因此,我们将stuff设置为null
stuff=null;
}
公共列表getStuff(){
if(stuff==null){
stuff=stuffFromJsonString(jsonStuff);
}
返回集合。不可修改列表(stuff);
}
公共空集凝灰岩(列表材料){
如果(未更改(物料)){
//新的内容列表与旧的内容列表相同。无需重新生成json。
返回;
}
this.stuff=新数组列表(stuff);
//名单变了
//因此,必须重新生成JSONSTAFF字符串
this.jsonstaff=null;
}
私有布尔值suffListNotChanged(列表填充列表){
...
}
私有字符串stuffToJsonString(列表stuffList){
if(stuffList==null){
....
}
}
私有列表stuffFromJsonString(字符串填充){
if(stuff==null){
....
}
}
}

您甚至不必担心应该注释哪个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);
     }

}
类MyTableObject{
@高球
@列(name=“stuff”)
私有列表stuffAsJsonString;
公共字符串getStuffAsJsonString(){
将stuff返回到JSonString(stuff);
}
公共setStuffFromJsonString(字符串jsonString){
stuff=stuffFromJsonString(jsonString);
}
}