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 オブジェクトをメモリにキャッシュすることで現在のソリューションのパフォーマンスを向上できることを感謝していますが、セッターが呼び出されるたびにそれらを 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);
     }

}

ただし、私の知る限り、注釈はゲッターでのみ有効です。オブジェクト内の 1 つの表現とデータベース内の別の表現を使用して、上記のようなことを達成できますか? 私は JPA を初めて使用するので、明らかな何かを簡単に見逃してしまう可能性があります。

よろしくお願いします

4

3 に答える 3

0

注釈がゲッターでのみ有効であるというわけではありません単一の注釈がゲッターとセッターを処理します。二重に注釈を付けることはありません。

つまり、基本的にはすでに理解しています。セッターの余分なものを取り外して@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

ゲッターに注釈を付けることができます。オブジェクトがデータベースからロードされると、対応するセッターが JPA によって使用されます。

JPA 専用の保護されたプロパティと、クライアント用のパブリック アクセサーを使用します。public アクセサーは、必要に応じて 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

ゲッター/セッターのどちらにアノテーションを付ける必要があるかを心配する必要さえありません。以下のコードはすべて設定されている必要があります。

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 に答える