1

QueryDsl を使用して SQL ステートメントを呼び出そうとしていますが、これは Spring Data JPA ではカバーできません。ここに私が実行したい文があります。

SELECT timestamp, deviceId 
  FROM EventData a
INNER JOIN
(SELECT max(timestamp) timestamp, deviceId 
   FROM EventData 
  GROUP BY deviceId) b
USING (timestamp,deviceId)
WHERE deviceId in ('1', '2')

そして、私は以下のようにしました:

@PersistenceContext
EntityManager em;

JPAQuery query = new JPAQuery(em);
QEventData eventData = new QEventData();

return
query.from(eventData)
     .innerJoin(
               query.from(eventData)
                    .groupBy(eventData.deviceId)
                    .list(eventData.deviceId, eventData.timestamp.max())
      ).on(eventData.deviceId.eq(?))
.where(eventData.deviceId.in("1", "2"))
.list(eventData);

innerJoinに何を入れたのかわかりません。QueryDsl の例を試してみましたが、正しいものが見つかりませんでした。QueryDsl の良い例はどこで入手できますか?

ありがとう、あなたの答えをいただければ幸いです。

4

1 に答える 1

1

これは部分的な答えにすぎませんが、JUnit テストでうまくいきました。JPAではなく、SQLクエリを使用しました。試す価値があります:

    Connection connection = getConnection();
    SQLTemplates dialect = new PostgresTemplates(); // TODO: use appropriate db template
    QEventData c = new QEventData("c");
    QEventData c2 = new QEventData("c2");

    // Use this to hold alias for inner select
    PathBuilder<Object[]> c2alias = new PathBuilder<Object[]>(Object[].class, "c2alias");

    SQLQuery query =  new SQLQuery(connection , dialect);
    return query.from(c).innerJoin(
           new SQLSubQuery().from(c2)
                .groupBy(c2.deviceid)
                .list(c2.device, c2.timestamp.max().as("timestamp")), c2alias
    ).on(c.deviceid.eq(c2alias.get("deviceid")),
        c.timestamp.eq(c2alias.get("timestamp")))
    .where(c.deviceid.in(1, 2))
            .list(c.deviceid, c.timestamp);

注 1: list() 関数では、選択するフィールドを明示的にリストする必要があります。そうしないと、PathBuilder 内部選択エイリアスの使用が原因であると思われるエラーが発生します。

注 2: 他の投稿では、これが JPA では機能しない可能性があることが示されています

注3:私が書いたSQLでは、USING句を知らない人のために、実際に使用されたことはありません:http://docs.oracle.com/javadb/10.8.1.2/ref/ rrefsqljusing.html

注 4: 上記が querydsl/JPA で機能しない場合は、EXISTS 句を使用するようにクエリをリファクタリングすることを検討してください。

于 2013-10-17T14:01:23.293 に答える