JPA JPQL/持久化查询语言

原文来自:http://www.yiibai.com/jpa/jpa_jpql.html#article-start

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

JPA 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

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

Package Hierarchy

急切和延迟加载

JPA中最重要的概念是为了使数据库的副本在高速缓冲存储器中。虽然有一个数据库事务,但JPA首先创建一个重复的数据集,只有当它使用实体管理提交,所做的更改影响到数据库中。

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

预先抓取

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

延迟加载

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

延迟装载可能在第一次尝试获取记录。这样一来,在整个记录的副本已经被存储在高速缓冲存储器中。性能方面,延迟装载最好。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值