1. 概要

このクイックチュートリアルでは、例を使用して、Hibernateで使用される addScalar()メソッドについて説明します。 この方法の使用方法と使用の利点を学びます。

2. addScalar()はどのような問題を解決しますか?

通常、ネイティブSQLクエリを使用してHibernateで結果をフェッチする場合は、 createNativeQuery()メソッドを使用し、続いて list()メソッドを使用します。

session.createNativeQuery("SELECT * FROM Student student")
  .list();

この場合、Hibernateは ResultSetMetadata 列の詳細を検索し、のリストを返します物体配列

ただし、 ResultSetMetadataを過度に使用すると、パフォーマンスが低下する可能性があります。ここで addScalar()メソッドが役立ちます。

addScalar()メソッドを使用することにより、HibernateがResultSetMetadataを使用するのを防ぐことができます。

3. addScalar()の使用方法は?

addScalar()メソッドを使用して、学生のリストをフェッチする新しいメソッドを作成しましょう。

public List<Object[]> fetchColumnWithScalar() {
    return session.createNativeQuery("SELECT * FROM Student student")
      .addScalar("studentId", StandardBasicTypes.LONG)
      .addScalar("name", StandardBasicTypes.STRING)
      .addScalar("age", StandardBasicTypes.INTEGER)
      .list();
}

ここでは、 addScalar()メソッドの引数として列名とそのデータ型を指定する必要があります。

現在、Hibernateは使用しません ResultSetMetadata で事前に定義している列の詳細を取得するには addScalar()。 したがって、以前のアプローチと比較してパフォーマンスが向上します。

4. その他の利点

addScalar()メソッドを使用できるいくつかのユースケースを見てみましょう。

4.1. 列数を制限する

addScalar()メソッドを使用して、queryによって返される列の数を制限することもできます。

学生名の列のみをフェッチする別のメソッドfetchLimitedColumnWithScalar()を作成してみましょう。

public List<String> fetchLimitedColumnWithScalar() {
    return session.createNativeQuery("SELECT * FROM Student student")
      .addScalar("name", StandardBasicTypes.STRING)
      .list();
}

ここでは、クエリでアスタリスクを使用して、学生のリストをフェッチしました。

SELECT * FROM Student student

ただし、 addScalar()で1つの列しか指定していないため、すべての列をフェッチするわけではなく、リストに1つの列nameのみを返します。 ] 方法。

fetchLimitedColumnWithScalar()メソッドによって返される列を検証するためのJUnitメソッドを作成しましょう。

List<String> list = scalarExample.fetchLimitedColumnWithScalar();
for (String colValue : list) {
    assertTrue(colValue.startsWith("John"));
}

ご覧のとおり、これにより、 Object 配列ではなく、文字列のListが返されます。 また、サンプルデータでは、「John」で始まるすべての学生名を保持しているため、上記の単体テストでそれに対して列の値をアサートしています。

これにより、返される内容に関してコードがより明確になります。

4.2. 単一のスカラー値を返す

addScalar()メソッドを使用して、リストの代わりに単一のスカラー値を直接返すこともできます。

すべての学生の平均年齢を返すメソッドを作成しましょう。

public Integer fetchAvgAgeWithScalar() {
    return (Integer) session.createNativeQuery("SELECT AVG(age) as avgAge FROM Student student")
      .addScalar("avgAge")
      .uniqueResult();
}

それでは、単体テスト方法で同じことを確認しましょう:

Integer avgAge = scalarExample.fetchAvgAgeWithScalar();
assertEquals(true, (avgAge >= 5 && avgAge <= 24));

ご覧のとおり、 fetchAvgAgeScalar()メソッドは Integer 値を直接返し、それをアサートしています。

サンプルデータでは、5〜24歳の学生のランダムな年齢を提供しています。 したがって、アサーション中、平均は5〜24になると予想されます。

同様に、 SQLの他の集計関数を使用して、addScalar()メソッドを使用して、count、max、min、sum、またはその他の単一のスカラー値を直接取得できます。

5. オーバーロードされたaddScalar()メソッド

オーバーロードされたaddScalar()メソッドもあり、単一の引数として列名のみを受け入れます

新しいメソッドを作成し、オーバーロードされた addScalar()メソッドを使用してみましょう。このメソッドは、タイプを指定せずに age列をフェッチします。

public List<Object[]> fetchWithOverloadedScalar() {
    return session.createNativeQuery("SELECT * FROM Student student")
      .addScalar("name", StandardBasicTypes.STRING)
      .addScalar("age")
      .list();
}

次に、別のJUnitメソッドを記述して、メソッドが2つ以上の列を返しているかどうかを確認しましょう。

List<Object[]> list = scalarExample.fetchColumnWithOverloadedScalar();
for (Object[] colArray : list) {
    assertEquals(2, colArray.length);
}

ご覧のとおり、これはObject配列のListを返し、配列のサイズは2で、リストの名前と年齢の列を表します。

6. 結論

この記事では、Hibernateでの addScalar()メソッドの使用法、使用方法、および使用時期を例とともに見てきました。

いつものように、これらの例のコードはGitHubから入手できます。