2

私は JPA (Hibernate) を使用するプロジェクトに取り組んでいるため、ほとんどすべてのクエリは JPQL で記述されています。しかし、クエリについては、特定のデータベース タイプに取り掛かる必要があるため、ネイティブ クエリを作成しました。

このプロジェクトは、実際には MySQL と Oracle DBMS の両方でテストされています。私のネイティブクエリは"SELECT 1 FROM [...]"; 次に、結果が存在するかどうか (簡単) と、それが 1 かどうかを知る必要があります (それは冗長であると主張できます:-))。

どちらの場合もjavax.persistence.QuerywithcreateNativeQuery(String)を作成し、次のようにクエリを実行しますObject r = q.getSingleResult();(例外は既に処理されています)。
私が見つけたのは、MySQL では r が aBigIntegerであるのに対し、Oracle では class であるということBigDecimalです。

私はJDBCにうんざりしています.データベースシステムがどのようなものに対して実行されても、クエリが同じデータ型を返すことを確認できる方法(クエリ、オブジェクト、または使用しているメソッド呼び出しを変更する)はありますか? ? これは構成できるものですか、jdbc に依存しますか、それともドライバー固有の問題ですか?

4

1 に答える 1

1

BigIntegerとはどちらもNumberBigDecimalのサブクラスです。したがって、共通のスーパータイプにキャストし、そのメソッドを使用して などのプリミティブ型にキャストするだけです。int

Number r = (Number) q.getSingleResult();
boolean isOne = (r.intValue() == 1);

Hibernate には、非常に便利なaddScalarメソッドもあります。詳細については、ドキュメントの第 18 章を参照してください。

このソリューションを使用する場合は、JPA レイヤーをアンラップし、ベンダー固有の API を使用することを意味することに注意してください。

Session session = entityManager.unwrap(Session.class);
Integer r = (Integer) session.createSQLQuery("SELECT 1 AS one FROM [...]")
   .addScalar("one", IntegerType.INSTANCE)
   .uniqueResult();

最後に、JPA には独自のSqlResultSetMappingアノテーションがあります。これにより、ネイティブの結果をエンティティにラップできます。JPA プロバイダーは、各データベース列をそれぞれのエンティティ フィールド タイプにキャストするために最善を尽くします。それでも、スカラー値の場合、オーバーヘッドが大きすぎます (最初のソリューションを使用します)。

于 2014-01-21T14:20:51.083 に答える