开发手册 欢迎您!
软件开发者资料库

JPA - JPQL

JPA JPQL - 使用这个初学者教程,简单易学地学习JPA,该教程包含从简介,体系结构,ORM组件,安装,实体管理器,JPQL,高级映射,实体关系和标准API开始的基础知识到高级知识。

本章介绍了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表包含以下记录.

EidEname薪水Deg
1201Gopal40000技术经理
1202Manisha40000校对读者
1203Masthanvali40000技术作家
1204Satish30000技术作家
1205Krishna30000Technical Writer
1206Kiran35000证明读者

com.it1352.eclipselink.service 包下创建一个名为 ScalarandAggregateFunctions.java 的类,如下所示.

package com.it1352.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 :GOPALEmployee NAME :MANISHAEmployee NAME :MASTHANVALIEmployee NAME :SATISHEmployee NAME :KRISHNAEmployee NAME :KIRANax Employee Salary :40000.0

之间,和,像关键字一样

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

com.it1352.eclipselink.service 下创建名为 BetweenAndLikeFunctions.java 的类b>包装如下:

package com.it1352.eclipselink.service; import java.util.List;import javax.persistence.EntityManager;import javax.persistence.EntityManagerFactory;import javax.persistence.Persistence;import javax.persistence.Query;import com.IT屋.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.0Employee ID :1202 Employee salary :40000.0Employee ID :1203 Employee salary :40000.0Employee ID :1204 Employee salary :30000.0Employee ID :1205 Employee salary :30000.0Employee ID :1206 Employee salary :35000.0Employee ID :1202 Employee name :ManishaEmployee ID :1203 Employee name :Masthanvali

订购

要在JPQL中订购记录,我们使用ORDER BY子句.此子句的用法与SQL中的用法相同,但它处理实体.按照示例顺序.

com.it1352.eclipselink.service 包下创建一个类Ordering.java,如下所示:

package com.it1352.eclipselink.service; import java.util.List;import javax.persistence.EntityManager;import javax.persistence.EntityManagerFactory;import javax.persistence.Persistence;import javax.persistence.Query;import com.IT屋.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 :GopalEmployee ID :1206 Employee Name :KiranEmployee ID :1205 Employee Name :KrishnaEmployee ID :1202 Employee Name :ManishaEmployee ID :1203 Employee Name :MasthanvaliEmployee ID :1204 Employee Name :Satish

命名查询

@NamedQuery注释被定义为具有预定义的不可更改查询字符串的查询.使用命名查询可以通过将JPQL查询字符串与POJO分离来改进代码组织,而不是动态查询.它还传递查询参数,而不是将文字动态嵌入到查询字符串中,从而提高查询效率.

首先,将@NamedQuery注释添加到名为的Employee实体类中在 com.it1352.eclipselink.entity 包下的Employee.java 如下:

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

package com.it1352.eclipselink.service; import java.util.List;import javax.persistence.EntityManager;import javax.persistence.EntityManagerFactory;import javax.persistence.Persistence;import javax.persistence.Query;import com.it1352.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如下:

 员工ID:1204员工姓名:Satish

添加上述所有类后,包层次结构如下所示:

包层次结构

渴望和延迟加载

JPA的主要概念是在缓存内存中创建数据库的副本.在与数据库进行交易时,首先它会对重复数据产生影响,并且只有在使用实体管理器提交时,才会对数据库进行更改.

有两种方法可以从中获取记录数据库 - 急切获取和懒惰提取.

渴望获取

使用主键查找记录时获取整个记录.

延迟提取

它检查是否有可用主键通知它(如果存在).然后,如果你调用该实体的任何getter方法,那么它将获取整个.

但是当你第一次尝试获取记录时,可以进行延迟提取.这样,整个记录的副本已经存储在高速缓冲存储器中.性能方面,懒惰的抓取是可取的.