📜  JPA-JPQL

📅  最后修改于: 2020-11-13 05:04:21             🧑  作者: Mango


本章介绍JPQL及其与持久性单元一起工作的方式。在本章中,示例遵循相同的包层次结构,我们在上一章中使用的如下:

JPA JPQL

Java持久性查询语言

JPQL是JPA规范中定义的Java持久性查询语言。它用于创建针对实体的查询以存储在关系数据库中。 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.tutorialspoint.eclipselink.service包下创建一个名为ScalarandAggregateFunctions.java的类。

package com.tutorialspoint.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 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

之间,和,像关键字

JPQL的主要关键字是’Between’,’And’和’Like’。这些关键字在查询中的Where子句之后使用。

com.tutorialspoint.eclipselink.service包下创建一个名为BetweenAndLikeFunctions.java的类,如下所示:

package com.tutorialspoint.eclipselink.service;

import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.Query;
import com.tutorialspoint.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 list=(List)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 list1=(List)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.tutorialspoint.eclipselink.service包下创建一个Ordering.java类,如下所示:

package com.tutorialspoint.eclipselink.service;

import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.Query;
import com.tutorialspoint.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 list = (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 :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分开来改善代码组织。它还传递查询参数,而不是将字面量动态地嵌入查询字符串,从而使查询效率更高。

首先,将@NamedQuery批注添加到com.tutorialspoint.eclipselink.entity包下名为Employee.java的Employee实体类中,如下所示:

package com.tutorialspoint.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.tutorialspoint.eclipselink.service包下创建一个名为NamedQueries.java的类,如下所示:

package com.tutorialspoint.eclipselink.service;

import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.Query;
import com.tutorialspoint.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 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的主要概念是在高速缓存中复制数据库。在与数据库进行事务处理时,首先它将影响重复数据,并且只有在使用实体管理器进行提交时,更改才会影响到数据库中。

有两种从数据库中获取记录的方法-渴望获取和惰性获取。

渴望获取

在使用主键查找记录的同时获取整个记录。

懒惰取

它检查是否存在通过主键进行通知的通知。然后,如果您调用该实体的任何getter方法,则它将获取整个实体。

但是,当您尝试首次获取记录时,可以进行延迟获取。这样,整个记录的副本已存储在缓存中。在性能方面,最好是延迟获取。