Java 在JPA中表示数据库表示和对象表示之间的差异
我正在使用一个遗留数据库,该数据库经常使用存储为文本的JSON块。我正在尝试编写一些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
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);
}
}