0

特定のテーブルの行にマップする POJO があります。行は、あるサイトの画像を記述し、幅、高さ、URL、ある種のステータス、その他のフィールドなどのデータを含みます。一部のレガシー コードにはhibernate、URL とステータスを返すクエリ ( ) があります。このデータはクラスにカプセル化されImageStatusAndOrigFilenameます。

次の理由から、これは悪い考えだと思います。

  1. 明日、他のフィールドを照会する必要がある場合はどうすればよいでしょうか? 名前がデータに結び付きすぎています。
  2. これまで、画像の幅と高さを取得する唯一の方法は、URL を解析することでした。今日、幅と高さを db にマッピングしたので、画像のサイズとステータスを取得する必要があります (元のファイル名はもう気にしません)。したがって、このクラスを変更する必要がありますが、コードの他の場所で使用されているため変更できません。特定のシナリオに結び付けられておらず、必要に応じて拡張できる、より一般的なものに到達したいと考えています。

使用するデータ構造を把握しようとしています。すべてのフィールドを持ち、それらの一部を null のままにしておく元の POJO を使用する必要があります (このシナリオではすべてのフィールドが必要ないため、すべてのフィールドを照会したくありません)。この特定のクエリ用に別の POJO を作成する必要がありますか (もちろん、より適切な名前を付けます)。

他の提案ももちろん大歓迎です。

編集

POJO:

@Entity
@Table(name = "web_image")
public class WebImage {
   private long id;

   private Document document;

   private Integer mediaType;

   private Integer width;

   private Integer height;

   private Date creationDate;

   private Date modificationDate;

   private String origUrl;

   private ImageStatus status;

   @Id
   @GeneratedValue(strategy = GenerationType.AUTO)
   @Column(name = "id")
   public Long getId() {
      return id;
   }

   @ManyToOne(fetch = FetchType.LAZY)
   @JoinColumn(name = "document_id")
   public Document getDocument() {
      return document;
   }

   public void setDocument(final OBDocument document) {
     this.document = document;
   }

   @Column(name = "width")
   public Integer getWidth() {
      return width;
   }

   public void setWidth(final Integer width) {
     this.width = width;
   }

   // Other getters and setters for the rest of the private fields
}

クエリ:

SELECT b.document_id , b.status , b.orig_file_id, a.min_id as id FROM web_image b, ( SELECT x.document_id, MAX(x.id) max_id, MIN(x.id) min_id FROM web_image x WHERE x.document_id in ( :docs ) GROUP BY x.document_id) a WHERE a.max_id = b.id

4

2 に答える 2

1

未使用の列をロードしないようにする必要があり、実際に節約する価値があるかどうかを判断するためにプロファイリングする必要がある場合、単純な解決策は JPA コンストラクター式を使用してクエリを記述することです。

JPQL:

http://docs.oracle.com/html/E24396_01/ejb3_langref.html#ejb3_langref_constructor

基準 API:

http://docs.jboss.org/hibernate/entitymanager/3.5/reference/en/html/querycriteria.html#querycriteria-typedquery-multiselect

これらの問題は、プロパティのセットごとにコンストラクターを追加する必要があることです。

Hibernate 固有のオプション - コンストラクターは不要:

Transformers.aliasToBean を参照してください。

Java - Hibernate の criteria.setResultTransformer() はモデル フィールドをデフォルト値で初期化します

これらすべてのオプションについて、他の DTO を使用するか、既存のエンティティを使用できます。つまり、アンマネージド インスタンスを返します。

遅延読み込み

フィールドを遅延ロードすることもできますが、バイトコード操作が必要です。

http://docs.jboss.org/hibernate/orm/3.3/reference/en/html/performance.html#performance-fetching-lazyproperties

コメントにも注意してください。

Hibernate3 は、個々のプロパティの遅延フェッチをサポートしています。この最適化手法は、フェッチ グループとも呼ばれます。これは主にマーケティング機能であることに注意してください。行の読み取りの最適化は、列の読み取りの最適化よりもはるかに重要です。ただし、クラスの一部のプロパティをロードするだけでも、極端な場合に役立ちます。

于 2013-11-07T10:57:45.460 に答える
1

これはどうですか:

@MappedSuperclass
public class ImageStatusAndOrigFilename {
...
}


@Entity
public class WebImage extends ImageStatusAndOrigFilename {
    ...
}

これで両方のクラスができました。古いものはエンティティではありませんが、そのクライアントはそれについて何も知りません。すべてのフェッチと永続化はWebImageクラスにありますが、クエリを実行できますImageStatusAndOrigFilename

于 2013-11-07T10:10:05.190 に答える