📅  最后修改于: 2020-11-13 05:04:21             🧑  作者: Mango
本章介绍JPQL及其与持久性单元一起工作的方式。在本章中,示例遵循相同的包层次结构,我们在上一章中使用的如下:
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方法,则它将获取整个实体。
但是,当您尝试首次获取记录时,可以进行延迟获取。这样,整个记录的副本已存储在缓存中。在性能方面,最好是延迟获取。