Jpa-jpql

提供:Dev Guides
移動先:案内検索

JPA-JPQL

この章では、JPQLと、それが永続性ユニットでどのように機能するかについて説明します。 この章では、例は前の章で使用したものと同じパッケージ階層に従います。

JPA JPQL

Java Persistence Query言語

JPQLは、JPA仕様で定義されているJava Persistence Query Languageです。 エンティティに対するクエリを作成して、リレーショナルデータベースに格納するために使用されます。 JPQLは、SQL構文に基づいて開発されています。 ただし、データベースには直接影響しません。

JPQLは、SELECT句を使用して情報またはデータを取得でき、UPDATE句とDELETE句を使用して一括更新を実行できます。 EntityManager.createQuery()APIは、言語のクエリをサポートします。

クエリ構造

JPQL構文は、SQLの構文に非常によく似ています。 SQLは単純な構造化照会言語であり、多くの開発者がアプリケーションで使用しているため、SQLのような構文を持つことは利点です。 SQLはリレーショナルデータベースのテーブル、レコード、およびフィールドに対して直接機能しますが、JPQLはJavaクラスおよびインスタンスに対して機能します。

たとえば、JPQLクエリは、SQLの場合のように、データベースからフィールド結果セットではなくエンティティオブジェクトを取得できます。 JPQLクエリ構造は次のとおりです。

SELECT ... FROM ...
[WHERE ...]
[GROUP BY ... [HAVING ...]]
[ORDER BY ...]

JPQLのDELETEおよびUPDATEクエリの構造は、次のように単純です。

DELETE FROM ... [WHERE ...]

UPDATE ... SET ... [WHERE ...]

スカラー関数と集計関数

スカラー関数は、入力値に基づいて結果値を返します。 集計関数は、入力値を計算して結果の値を返します。

前の章で使用したのと同じ従業員管理の例に従ってください。 ここでは、JPQLのスカラー関数と集計関数を使用してサービスクラスを調べます。

jpadb.employeeテーブルに次のレコードが含まれていると仮定しましょう。

Eid Ename Salary Deg
1201 Gopal 40000 Technical Manager
1202 Manisha 40000 Proof Reader
1203 Masthanvali 40000 Technical Writer
1204 Satish 30000 Technical Writer
1205 Krishna 30000 Technical Writer
1206 Kiran 35000 Proof Reader

次のように、 com.finddevguides.eclipselink.service パッケージの下に ScalarandAggregateFunctions.java という名前のクラスを作成します。

package com.finddevguides.eclipselink.service;

import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.Query;

public class ScalarandAggregateFunctions {
   public static void main( String[ ] args ) {

      EntityManagerFactory emfactory = Persistence.createEntityManagerFactory( "Eclipselink_JPA" );
      EntityManager entitymanager = emfactory.createEntityManager();

     //Scalar function
      Query query = entitymanager.
      createQuery("Select UPPER(e.ename) from Employee e");
      List<String> list = query.getResultList();

      for(String e:list) {
         System.out.println("Employee NAME :"+e);
      }

     //Aggregate function
      Query query1 = entitymanager.createQuery("Select MAX(e.salary) from Employee e");
      Double result = (Double) query1.getSingleResult();
      System.out.println("Max Employee Salary :" + result);
   }
}

上記のプログラムをコンパイルして実行すると、次のようにEclipse IDEのコンソールパネルに出力が表示されます。

Employee NAME :GOPAL
Employee NAME :MANISHA
Employee NAME :MASTHANVALI
Employee NAME :SATISH
Employee NAME :KRISHNA
Employee NAME :KIRAN
ax Employee Salary :40000.0

Between、And、Likeキーワード

「間」、「そして」、「いいね」はJPQLの主要なキーワードです。 これらのキーワードは、クエリのWhere句の後に使用されます。

次のように、 com.finddevguides.eclipselink.service パッケージの下に BetweenAndLikeFunctions.java という名前のクラスを作成します。

package com.finddevguides.eclipselink.service;

import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.Query;
import com.finddevguides.eclipselink.entity.Employee;

public class BetweenAndLikeFunctions {
   public static void main( String[ ] args ) {

      EntityManagerFactory emfactory = Persistence.createEntityManagerFactory( "Eclipselink_JPA" );
      EntityManager entitymanager = emfactory.createEntityManager();

     //Between
      Query query = entitymanager.createQuery( "Select e " + "from Employee e " + "where e.salary " + "Between 30000 and 40000" );

      List<Employee> list=(List<Employee>)query.getResultList( );

      for( Employee e:list ){
         System.out.print("Employee ID :" + e.getEid( ));
         System.out.println("\t Employee salary :" + e.getSalary( ));
      }

     //Like
      Query query1 = entitymanager.createQuery("Select e " + "from Employee e " + "where e.ename LIKE 'M%'");

      List<Employee> list1=(List<Employee>)query1.getResultList( );

      for( Employee e:list1 ) {
         System.out.print("Employee ID :"+e.getEid( ));
         System.out.println("\t Employee name :"+e.getEname( ));
      }
   }
}

上記のプログラムをコンパイルして実行すると、次のようにEclipse IDEのコンソールパネルに出力が表示されます。

Employee ID :1201    Employee salary :40000.0
Employee ID :1202    Employee salary :40000.0
Employee ID :1203    Employee salary :40000.0
Employee ID :1204    Employee salary :30000.0
Employee ID :1205    Employee salary :30000.0
Employee ID :1206    Employee salary :35000.0

Employee ID :1202    Employee name :Manisha
Employee ID :1203    Employee name :Masthanvali

ご注文

JPQLでレコードを並べ替えるには、ORDER BY句を使用します。 この句の使用法はSQLでの使用法と同じですが、エンティティを扱います。 例による順序に従ってください。

次のように com.finddevguides.eclipselink.service パッケージの下にクラスOrdering.javaを作成します。

package com.finddevguides.eclipselink.service;

import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.Query;
import com.finddevguides.eclipselink.entity.Employee;

public class Ordering {

   public static void main( String[ ] args ) {
      EntityManagerFactory emfactory = Persistence.createEntityManagerFactory( "Eclipselink_JPA" );
      EntityManager entitymanager = emfactory.createEntityManager();

     //Between
      Query query = entitymanager.createQuery( "Select e " + "from Employee e " + "ORDER BY e.ename ASC" );

      List<Employee> list = (List<Employee>)query.getResultList( );

      for( Employee e:list ) {
         System.out.print("Employee ID :" + e.getEid( ));
         System.out.println("\t Employee Name :" + e.getEname( ));
      }
   }
}

上記のプログラムをコンパイルして実行すると、次のようにEclipse IDEのコンソールパネルに出力が表示されます。

Employee ID :1201    Employee Name :Gopal
Employee ID :1206    Employee Name :Kiran
Employee ID :1205    Employee Name :Krishna
Employee ID :1202    Employee Name :Manisha
Employee ID :1203    Employee Name :Masthanvali
Employee ID :1204    Employee Name :Satish

名前付きクエリ

@NamedQueryアノテーションは、定義済みの変更不可能なクエリ文字列を持つクエリとして定義されます。 動的なクエリの代わりに、名前付きクエリを使用すると、JPQLクエリ文字列をPOJOから分離することにより、コード編成を改善できます。 また、リテラルをクエリ文字列に動的に埋め込むのではなく、クエリパラメータを渡し、より効率的なクエリを実現します。

まず、次のように、* Name.Queryアノテーションを com.finddevguides.eclipselink.entity パッケージの Employee.java という名前のEmployeeエンティティクラスに追加します。

package com.finddevguides.eclipselink.entity;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.NamedQuery;
import javax.persistence.Table;

@Entity
@Table
@NamedQuery(query = "Select e from Employee e where e.eid = :id", name = "find employee by id")

public class Employee {
   @Id
   @GeneratedValue(strategy = GenerationType.AUTO)

   private int eid;
   private String ename;
   private double salary;
   private String deg;

   public Employee(int eid, String ename, double salary, String deg) {
      super( );
      this.eid = eid;
      this.ename = ename;
      this.salary = salary;
      this.deg = deg;
   }

   public Employee( ) {
      super();
   }

   public int getEid( ) {
      return eid;
   }

   public void setEid(int eid) {
      this.eid = eid;
   }

   public String getEname( ) {
      return ename;
   }

   public void setEname(String ename) {
      this.ename = ename;
   }

   public double getSalary( ) {
      return salary;
   }

   public void setSalary(double salary) {
      this.salary = salary;
   }

   public String getDeg( ) {
      return deg;
   }

   public void setDeg(String deg) {
      this.deg = deg;
   }

   @Override
   public String toString() {
      return "Employee [eid=" + eid + ", ename=" + ename + ", salary=" + salary + ", deg=" + deg + "]";
   }
}

次のように、 com.finddevguides.eclipselink.service パッケージの下に NamedQueries.java という名前のクラスを作成します。

package com.finddevguides.eclipselink.service;

import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.Query;
import com.finddevguides.eclipselink.entity.Employee;

public class NamedQueries {
   public static void main( String[ ] args ) {

      EntityManagerFactory emfactory = Persistence.createEntityManagerFactory( "Eclipselink_JPA" );
      EntityManager entitymanager = emfactory.createEntityManager();
      Query query = entitymanager.createNamedQuery("find employee by id");

      query.setParameter("id", 1204);
      List<Employee> list = query.getResultList( );

      for( Employee e:list ){
         System.out.print("Employee ID :" + e.getEid( ));
         System.out.println("\t Employee Name :" + e.getEname( ));
      }
   }
}

上記のプログラムをコンパイルして実行すると、次のようにEclipse IDEのコンソールパネルに出力が表示されます。

Employee ID :1204    Employee Name :Satish

上記のすべてのクラスを追加すると、パッケージ階層は次のように表示されます。

パッケージ階層

熱心で遅延読み込み

JPAの主な概念は、キャッシュメモリにデータベースの複製コピーを作成することです。 データベースとのトランザクション中、最初は重複データに影響し、エンティティマネージャーを使用してコミットされた場合にのみ、変更がデータベースに反映されます。

データベースからレコードを取得する方法には、熱心な取得と遅延取得の2つの方法があります。

熱心なフェッチ

主キーを使用してレコードを検索しながら、レコード全体を取得します。

遅延フェッチ

プライマリキーが存在する場合、通知の可用性をチェックします。 その後、そのエンティティのgetterメソッドのいずれかを呼び出すと、全体が取得されます。

ただし、初めてレコードをフェッチしようとすると、遅延フェッチが可能です。 これにより、レコード全体のコピーが既にキャッシュメモリに保存されます。 パフォーマンスに関しては、遅延フェッチが望ましいです。