0

私はテーブルを持っています

MyTable (myId,myStringCol1,myStringCol2,myStringCol3)

使用する場合

QUERY1

hibernateTemplate.find("SELECT new(myId,myStringCol1) from MyTable")

MyTableオブジェクトを取得しています。このため、MyTableクラスには次のようなコンストラクターが1つあるはずです。

MyTable{
      MyTable(Integer id,String col1){
          this.id = id;
          this.col1 = col1;
       }

}

しかし、別の方法で私がこのように呼んでいるとき

QUERY2

hibernateTemplate.find("SELECT new(myId,myStringCol2) from MyTable")  ///myStringCol2

ここでも、上記のように1つのコンストラクターがありますが、同じ署名コンストラクターを作成することはできません。したがって、2番目のクエリ(QUERY2)を実行すると、最初のコンストラクターが原因でcol1のmyStringCol2値が取得されます。

では、どうすればこの問題を解決できますか。

提案を待っています。

4

3 に答える 3

2

まず第一に、どちらの場合も単純に完全なエンティティを選択することになります。これは、パフォーマンスの点で大きな違いはなく、エンティティが添付されているため、はるかに単純になるからです。

技術的な質問に答えるために、結果に対するループを自分で実装するだけです。

String hql = "select mt.myId, mt.myStringCol2 from MyTable mt";
List<Object[]> rows = session.createQuery(hql).list();
List<MyTableDTO> result = new ArrayList<MyTableDTO>(rows.size());
for (Object[] row : rows) {
    result.add(new MyTableDTO((Long) row[0], (String) row[1]));
}

それと同じくらい簡単で、追加のボーナスとしてリファクタリング可能なコードが得られます.

また、このようなクエリの結果を格納するためにエンティティ クラスを使用しないことを強くお勧めします。クエリによって返されるフィールドのみを含む特定の DTO オブジェクトを作成します。メソッドがエンティティ クラスのインスタンスを返す場合、呼び出し元は、適切に、完全に設定され、添付されたエンティティ インスタンスを取得することを期待します。

于 2012-06-18T07:20:25.273 に答える
1

How about this:

class MyTable1{
      MyTable1(Integer id,String col1, String col2){
          this.id = id;
          this.col1 = col1;
          this.col2 = col2;
       }

}

And then:

Q1

hibernateTemplate.find("SELECT new(myId,myStringCol1,'') from MyTable")

Q2

hibernateTemplate.find("SELECT new(myId,'',myStringCol2) from MyTable") 

Would be nice if you could pass null instead of '', but AFAIK you can not, because there is a bug that prevents you from doing that: https://forum.hibernate.org/viewtopic.php?f=1&t=985612&start=0. So, you will have to use ''

Another option, inspired by Talha answer would be:

class MyTable{
      MyTable(Integer id,String col1, Boolean isColumn2){
          this.id = id;
          if(isColumn2){
             this.col2 = col2;
          }
          else{
             this.col1 = col1;
          }
      }      
}

Then you can just write:

Q1

hibernateTemplate.find("SELECT new(myId,myStringCol1,false) from MyTable")

Q2

hibernateTemplate.find("SELECT new(myId,myStringCol2,true) from MyTable") 
于 2012-06-18T07:14:29.897 に答える
0

必要なのは別の DTO です。

MyTableDto {
      MyTableDto1(Integer id,String col) {
          this.id = id;
          this.col = col;
       }

}

次に、次のように列を個別にクエリできます。

hibernateTemplate.find("SELECT new MyTableDto(t.id,t.myStringCol1) from MyTable t");

hibernateTemplate.find("SELECT new MyTableDto(t.id,t.myStringCol2) from MyTable t");

コードからあいまいさをさらに取り除き、もう少し読みやすくするために、2 つの別個の DTO オブジェクトを作成できます (名前だけが異なりますが、保持するデータが異なるため、コードが読みやすくなります)。

于 2012-06-18T07:26:41.750 に答える