38

プロジェクトでSpring Data JPAを使用しています。私は何百万ものレコードで遊んでいます。さまざまなテーブルのデータをフェッチし、オブジェクトを構築してから UI にペイントする必要があるという要件があります。これを実現する方法は、Spring データ リポジトリです。名前付きネイティブクエリによって実現できることを読みました。

名前付きネイティブ クエリがエンティティまたはエンティティのリストを返さない場合は、 @SqlResultSetMapping アノテーションを使用して、クエリ結果を正しい戻り値の型にマップできます。

しかし、私が使用しようとする@SqlResultSetMappingと、別のentityResultを取ります。私が理解していることは、一部のクエリ結果をエンティティ結果セットのみに変換するだけであるということですが、非エンティティ オブジェクトの結果セットが必要です。

@SqlResultSetMapping(
    name="studentPercentile",
    entities={
        @EntityResult(
           entityClass=CustomStudent.class,
              fields={
                  @FieldResult(name="id", column="ID"),
                  @FieldResult(name="firstName", column="FIRST_NAME"),
                   @FieldResult(name="lastName", column="LAST_NAME")
              }         
        )
   }
) 
@NamedNativeQuery(
    name="findStudentPercentile", 
    query="SELECT * FROM STUDENT", 
    resultSetMapping="studentPercentile")

上記の例では、学生エンティティからエンティティではない別の pojo ' CustomStudent 'に結果を取得しようとしています。(この例は、POC の目的のためだけに実行しようとしています。実際のユースケースは非常に複雑で、複雑なクエリが異なる結果セットを返します)。

上記のユースケースを達成するには?私のリポジトリメソッドが非エンティティオブジェクトを返す名前クエリを使用する以外に他の方法はありますか?

4

4 に答える 4

26

次のようなことができます

@NamedQuery(name="findWhatever", query="SELECT new path.to.dto.MyDto(e.id, e.otherProperty) FROM Student e WHERE e.id = ?1")

次に、 MyDto オブジェクトには、正しいフィールドで定義されたコンストラクターが必要です。

public MyDto(String id, String otherProperty) { this.id = id; this.otherProperty = otherProperty; }
于 2015-02-24T15:26:54.203 に答える
24

初めてこれに遭遇したときは非常に驚きましたが、@SqlResultSetMapping を使用してクエリ結果をスカラーとマネージド エンティティにのみマップできます。

あなたができる最善のことは、自動マッピングをスキップすることだと思います。マッピングなしのクエリが返さList<Object[]>れ、必要な方法でマッピングできます。

別のアプローチは、@MappedSuperclass を使用することです。@MappedSuperclass (あなたの場合は CustomStudent) として示されるクラスは、@SqlResultSetMapping で (100% とは言えませんが) 使用できます。ただし、継承階層を導入する必要があります。つまり、Student エンティティは CustomStudent を拡張する必要があります。継承は少し人工的であるため、適切なOO設計からはほとんどの場合、それはうまくいきません...

于 2013-05-07T17:01:04.730 に答える
18

JPA 2.1 ConstructorResultはどうですか?

@SqlResultSetMapping(
    name="studentPercentile",
    classes={
        @ConstructorResult(
            targetClass=CustomStudent.class,
            columns={
                @ColumnResult(name="ID"),
                @ColumnResult(name="FIRST_NAME"),
                @ColumnResult(name="LAST_NAME")
            }
        )
    }
)

@NamedNativeQuery(name="findStudentPercentile", query="SELECT * FROM STUDENT", resultSetMapping="studentPercentile")
于 2015-08-12T13:27:38.933 に答える