您的位置:首页 > 编程语言 > Java开发

JPA JPQL/持久化查询语言

2017-04-20 16:37 405 查看
本章介绍有关JPQL和它的工作原理与持久性单元。在这一章中,给出的例子遵循相同的包层次结构,和我们在前面的章节中使用一样。



Java持久化查询语言

JPQL代表Java持久化查询语言。它被用来创建针对实体的查询存储在关系数据库中。 JPQL是基于SQL语法的发展。但它不会直接影响到数据库。
JPQL可以检索使用SELECT子句中的数据,可以使用 UPDATE子句做批量UPDATE和DELETE子句。

查询结构

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 表包含下述记录。

EidEnameSalaryDeg
1201Gopal40000技术经理
1202Manisha40000接待员
1203Masthanvali40000技术作家
1204Satish30000技术作家
1205Krishna30000技术作家
1206Kiran35000接待员
创建一个在 com.yiibai.eclipselink.service 包命名为 ScalarandAggregateFunctions.java类如下。

package com.yiibai.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
Max Employee Salary :40000.0

Between, And, Like 关键词

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

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

package com.yiibai.eclipselink.service;

import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.Query;
import com.yiibai.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中的用法,但它涉及的实体。下面的示例演示了如何使用ORDER BY子句。

在com.yiibai.eclipselink.service包中创建类 Ordering.java 如下:

package com.yiibai.eclipselink.service;

import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.Query;
import com.yiibai.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注解被定义为一个预定义的查询字符串,它是不可改变的查询。相反,动态查询,命名查询可以通过POJO分离JPQL查询字符串提高代码的组织。它也传送的查询参数,而不是动态地嵌入文本到查询字符串,并因此产生更高效的查询。

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

package com.yiibai.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.yiibai.eclipselink.service包下的NamedQueries.java类,如下所示:

package com.yiibai.eclipselink.service;

import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.Query;
import com.yiibai.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中最重要的概念是为了使数据库的副本在高速缓冲存储器中。虽然有一个数据库事务,但JPA首先创建一个重复的数据集,只有当它使用实体管理提交,所做的更改影响到数据库中。

从数据库中获取记录有两种方式。

预先抓取

在预先抓取,相关的子对象获取一个特定的记录自动上传。

延迟加载

在延迟装载,涉及的对象不会自动上传,除非你特别要求他们。首先,它检查相关对象和通知可用性。以后,如果调用任何实体的getter方法,那么它获取的所有记录。

延迟装载可能在第一次尝试获取记录。这样一来,在整个记录的副本已经被存储在高速缓冲存储器中。性能方面,延迟装载最好。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java mysql jpa hibernate