目录

JPA - 快速指南

JPA - Introduction

任何企业应用程序都通过存储和检索大量数据来执行数据库操作。 尽管所有可用的存储管理技术,应用程序开发人员通常都很难有效地执行数据库操作。

通常,Java开发人员使用大量代码,或使用专有框架与数据库交互,而使用JPA,与数据库交互的负担显着减少。 它构成了对象模型(Java程序)和关系模型(数据库程序)之间的桥梁。

关系模型和对象模型之间的不匹配

关系对象以表格格式表示,而对象模型以对象格式的互连图表示。 在从关系数据库中存储和检索对象模型时,由于以下原因会发生一些不匹配:

  • Granularity :对象模型比关系模型更具粒度。

  • Subtypes :所有类型的关系数据库都不支持子类型(意味着继承)。

  • Identity :与对象模型一样,关系模型在写同等性时不会暴露身份。

  • Associations :在查看对象域模型时,关系模型无法确定多个关系。

  • Data navigation :对象网络中对象之间的数据导航在两个模型中都是不同的。

什么是JPA?

Java Persistence API是一组类和方法,用于将大量数据持久存储到Oracle Corporation提供的数据库中。

哪里可以使用JPA?

为了减轻为关系对象管理编写代码的负担,程序员遵循“JPA Provider”框架,该框架允许与数据库实例轻松交互。 这里所需的框架由JPA接管。

JPA

JPA历史

早期版本的EJB,使用javax.ejb.EntityBean接口定义持久层与业务逻辑层相结合。

  • 在介绍EJB 3.0时,持久层被分离并指定为JPA 1.0(Java Persistence API)。 该API的规范与JAVA EE5的规范一起于2006年5月11日使用JSR 220发布。

  • JPA 2.0于2009年12月10日作为Java Community Process JSR 317的一部分与JAVA EE6的规范一起发布。

  • JPA 2.1于2013年4月22日使用JSR 338以JAVA EE7规范发布。

JPA提供商

JPA是一个开源API,因此Oracle,Redhat,Eclipse等各种企业供应商通过在其中添加JPA持久性风格来提供新产品。 其中一些产品包括:

Hibernate, Eclipselink, Toplink, Spring Data JPA, etc.

JPA - Architecture

Java Persistence API是将业务实体存储为关系实体的源。 它显示了如何将PLAIN OLD JAVA OBJECT(POJO)定义为实体以及如何管理具有关系的实体。

类级架构

下图显示了JPA的类级体系结构。 它显示了JPA的核心类和接口。

JPAclass架构

下表描述了上述体系结构中显示的每个单元。

单位 描述
EntityManagerFactory 这是EntityManager的工厂类。 它创建和管理多个EntityManager实例。
EntityManager 它是一个接口,它管理对象的持久性操作。 它的工作方式类似于Query实例的工厂。
Entity 实体是持久性对象,存储为数据库中的记录。
EntityTransaction 它与EntityManager具有一对一的关系。 对于每个EntityManager,操作由EntityTransaction类维护。
Persistence 此类包含用于获取EntityManagerFactory实例的静态方法。
Query 此接口由每个JPA供应商实现,以获取满足条件的关系对象。

上述类和接口用于将实体作为记录存储到数据库中。 它们通过减少编写用于将数据存储到数据库中的代码的努力来帮助程序员,以便他们可以专注于更重要的活动,例如编写用于使用数据库表映射类的代码。

JPAclass关系

在上面的体系结构中,类和接口之间的关系属于javax.persistence包。 下图显示了它们之间的关系。

JPAclass关系
  • EntityManagerFactory和EntityManager之间的关系是one-to-many 。 它是EntityManager实例的工厂类。

  • EntityManager和EntityTransaction之间的关系是one-to-one 。 对于每个EntityManager操作,都有一个EntityTransaction实例。

  • EntityManager和Query之间的关系是one-to-many 。 可以使用一个EntityManager实例执行许多查询。

  • EntityManager和Entity之间的关系是one-to-many 。 一个EntityManager实例可以管理多个实体。

JPA - ORM Components

大多数现代应用程序使用关系数据库来存储数据。 最近,许多供应商转而使用对象数据库来减轻数据维护的负担。 这意味着对象数据库或对象关系技术正在负责存储,检索,更新和维护数据。 此对象关系技术的核心部分是映射orm.xml文件。 由于xml不需要编译,因此我们可以轻松地对管理多个数据源进行更改。

对象关系映射

对象关系映射(ORM)简要介绍了什么是ORM以及它是如何工作的。 ORM是一种编程功能,可以将数据从对象类型转换为关系类型,反之亦然。

ORM的主要功能是将对象映射或绑定到数据库中的数据。 在映射时,我们必须考虑数据,数据类型及其与自身实体或任何其他表中的实体的关系。

高级功能

  • Idiomatic persistence :它使您能够使用面向对象的类编写持久性类。

  • High Performance :它有许多提取技术和有希望的锁定技术。

  • Reliable :它非常稳定,并被许多专业程序员使用。

ORM架构

ORM架构如下所示。

对象关系映射

上述架构解释了如何将对象数据分三个阶段存储到关系数据库中。

Phase1

第一个阶段,称为object data phase ,包含POJO类,服务接口和类。 它是主要的业务组件层,具有业务逻辑操作和属性。

例如,让我们将员工数据库作为模式。

  • Employee POJO类包含ID,名称,工资和指定等属性。 它还包含这些属性的setter和getter等方法。

  • Employee DAO/Service类包含服务方法,例如create employee,find employee和delete employee。

阶段2

第二阶段,称为mappingpersistence phase ,包含JPA提供程序,映射文件(ORM.xml),JPA加载程序和对象网格。

  • JPA Provider :它是包含JPA flavor(javax.persistence)的供应商产品。 例如Eclipselink,Toplink,Hibernate等。

  • Mapping file :映射文件(ORM.xml)包含POJO类中的数据与关系数据库中的数据之间的映射配置。

  • JPA Loader :JPA加载器的工作方式类似于缓存。 它可以加载关系网格数据。 它的工作方式类似于数据库的副本,以便与POJO数据的服务类(POJO类的属性)进行交互。

  • Object Grid :它是一个临时位置,可以存储关系数据的副本,如高速缓存。 对数据库的所有查询首先对对象网格中的数据进行。 只有在提交后,它才会影响主数据库。

第3阶段

第三阶段是relational data phase 。 它包含逻辑上连接到业务组件的关系数据。 如上所述,仅当业务组件提交数据时,它才被物理地存储到数据库中。 在此之前,修改后的数据作为网格格式存储在高速缓冲存储器中。 获取数据的过程与存储数据的过程相同。

上述三个阶段的程序化交互机制称为object relational mapping

Mapping.xml

mapping.xml文件用于指示JPA供应商将Entity类映射到数据库表。

让我们举一个包含四个属性的Employee实体的例子。 名为Employee.java的Employee实体的POJO类如下:

public class Employee 
{
	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;
	}
}

上面的代码是Employee实体POJO类。 它包含四个属性eidenamesalarydeg 。 将这些属性视为表中的表字段,将eid视为此表的主键。 现在我们必须为它设计hibernate映射文件。 名为mapping.xml的映射文件如下:

<? xml version="1.0" encoding="UTF-8" ?>
<entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm    
                        http://java.sun.com/xml/ns/persistence/orm_1_0.xsd"
                        version="1.0">
    <description> XML Mapping file</description>
    <entity class="Employee">        
        <table name="EMPLOYEETABLE"/>
        <attributes>
            <id name="eid">
                <generated-value strategy="TABLE"/>
            </id>
            <basic name="ename">
                <column name="EMP_NAME" length="100"/>
            </basic>
            <basic name="salary">
            </basic>
            <basic name="deg">
            </basic>
        </attributes>
    </entity>
</entity-mappings>

上面的脚本用于将实体类映射到数据库表。 在这个文件中

  • 《entity-mappings》 :tag定义模式定义以允许实体标签进入xml文件。

  • 《description》 :标签提供有关应用程序的描述。

  • 《entity》 :tag定义要在数据库中转换为表的实体类。 Attribute类定义POJO实体类名。

  • 《table》 :标签定义表名。 如果您希望类和表都具有相同的名称,则不需要此标记。

  • 《attributes》 :标签定义属性(表中的字段)。

  • 《id》 :tag定义表的主键。 《generated-value》标签定义了如何分配主键值,例如AutomaticManual或从Sequence

  • 《basic》 :标记用于定义表的剩余属性。

  • 《column-name》 :tag用于在表中定义用户定义的表字段名称。

注解 Annotations

通常,xml文件用于配置特定组件或映射两个不同规范的组件。 在我们的例子中,我们必须在框架中单独维护xml文件。 这意味着在编写映射xml文件时,我们需要将mapping子文件中的POJO类属性与实体标记进行比较。

这是解决方案。 在类定义中,我们可以使用注释编写配置部分。 注释用于类,属性和方法。 注释以“@”符号开头。 注释在类,属性或方法之前声明。 JPA的所有注释都在javax.persistence包中定义。

这里给出了我们的例子中使用的注释列表。

注解 描述
@Entity 将类声明为实体或表。
@Table 声明表名。
@Basic 明确指定非约束字段。
@Embedded 指定类或属性的属性,其值是可嵌入类的实例。
@Id 指定属性,用于类的标识(表的主键)。
@GeneratedValue 指定如何初始化标识属性,例如自动,手动或从序列表中获取的值。
@Transient 指定非持久性的属性,即该值永远不会存储在数据库中。
@Column 指定持久性属性的列属性。
@SequenceGenerator 指定@GeneratedValue批注中指定的属性的值。 它创建了一个序列。
@TableGenerator 指定@GeneratedValue批注中指定的属性的值生成器。 它创建了一个价值生成表。
@AccessType 此类注释用于设置访问类型。 如果设置@AccessType(FIELD),则会按字段进行访问。 如果设置@AccessType(PROPERTY),则访问将发生属性。
@JoinColumn 指定实体关联或实体集合。 这用于多对一和一对多关联。
@UniqueConstraint 指定主表或辅助表的字段和唯一约束。
@ColumnResult 使用select子句引用SQL查询中列的名称。
@ManyToMany 定义连接表之间的多对多关系。
@ManyToOne 定义连接表之间的多对一关系。
@OneToMany 定义连接表之间的一对多关系。
@OneToOne 定义连接表之间的一对一关系。
@NamedQueries 指定命名查询的列表。
@NamedQuery 使用静态名称指定查询。

Java Bean标准

Java类将实例值及其行为封装到一个名为object的单元中。 Java Bean是临时存储和可重用组件或对象。 它是一个可序列化的类,它有一个默认的构造函数和getter和setter方法来单独初始化实例属性。

Bean约定

  • Bean包含其默认构造函数或包含序列化实例的文件。 因此,bean可以实例化另一个bean。

  • bean的属性可以分为布尔属性或非布尔属性。

  • 非布尔属性包含gettersetter方法。

  • 布尔属性包含setter并且is方法。

  • 任何属性的Getter方法都应该从小字母get (java方法约定)开始,并继续使用以大写字母开头的字段名称。 例如,字段名称是salary因此该字段的getter方法是getSalary ()

  • 任何属性的Setter方法都应该以小字母set (java方法约定)开头,继续使用以大写字母开头的字段名称和要设置为字段的argument value 。 例如,字段名称是salary因此该字段的setter方法是setSalary ( double sal )

  • 对于Boolean属性, is检查它是true还是false的方法。 例如,布尔属性为empty ,此字段的方法是isEmpty ()

JPA - Installation

本章将指导您完成在基于Windows和Linux的系统上设置JPA的过程。 JPA可以通过几个简单的步骤轻松安装并与您当前的Java环境集成,无需任何复杂的设置过程。 安装时需要用户管理。

系统需求 (System Requirements)

JDK Java SE 2 JDK 1.5或以上版本
Memory 1 GB RAM(推荐)
磁盘空间 没有最低要求
操作系统版本 Windows XP或更高版本,Linux

现在让我们继续安装JPA的步骤。

第1步:验证Java安装

首先,您需要在系统上安装Java软件开发工具包(SDK)。 要验证这一点,请根据您正在使用的平台执行以下两个命令中的任何一个。

如果Java安装已正确完成,那么它将显示Java安装的当前版本和规范。 下表给出了示例输出。

平台 命令 样本输出
Windows

打开命令控制台并键入:

\》java –version

Java版“1.7.0_60”

Java(TM)SE运行时环境(版本1.7.0_60-b19)

Java Hotspot(TM)64位服务器VM(内置24.60-b09,混合模式)

Linux

打开命令终端并输入:

$java –version

java版“1.7.0_25”

打开JDK运行时环境(rhel-2.3.10.4.el6_4-x86_64)

打开JDK 64位服务器VM(内置23.7-b01,混合模式)

第2步:设置Java环境

将环境变量JAVA_HOME设置为指向计算机上安装Java的基本目录位置。 例如,

平台 描述
Windows 将JAVA_HOME设置为C:\ProgramFiles\java\jdk1.7.0_60
Linux 导出JAVA_HOME =/usr/local/java-current

将Java编译器位置的完整路径附加到系统路径。

平台 描述
Windows 将字符串“C:\Program Files\Java\jdk1.7.0_60\bin”附加到系统变量PATH的末尾。
Linux 导出PATH = $ PATH:$ JAVA_HOME/bin/

如上所述,从命令提示符执行命令java -version

第3步:安装JPA

您可以使用本教程中的任何JPA Providers进行JPA安装,例如Eclipselink,Hibernate。 让我们使用Eclipselink跟踪JPA安装。 对于JPA编程,我们需要遵循特定的文件夹框架,因此最好使用IDE。

从链接https://www.eclipse.org/downloads/下载Eclipse IDE表单。选择Eclipse indien的EclipseIDE for JavaEE开发人员。

在C盘中解压缩Eclipse zip文件。 打开Eclipse IDE。

安装JPA

使用Eclipselink安装JPA

Eclipselink是一个库,因此我们无法将其直接添加到Eclipse IDE中。 要使用Eclipselink安装JPA,您需要按照以下步骤操作。

  • 通过在Eclipse IDE中选择File-》New-》JPA Project来创建一个新的JPA项目,如下所示:

    新JPA
  • 您将看到一个名为New JPA Project的对话框。 输入项目名称iowiki_JPA_Eclipselink ,检查jre版本并单击下一步:

    对话框
  • 单击用户库部分中的下载库(如果您没有库)。

    下载库
  • 在“下载库”对话框中选择最新版本的Eclipselink库,然后单击“下一步”,如下所示:

    下载库对话框
  • 接受许可条款,然后单击下载完成下载库。

    执照
  • 6.下载开始,如下面的屏幕截图所示。

    处理
  • 下载后,在用户库部分中选择下载的库,然后单击完成。

    图书馆科
  • 最后,您将在Eclipse IDE的Package Explorer中获取项目文件。 提取所有文件,您将获得文件夹和文件层次结构,如下所示:

    Package Explorer

将MySQL连接器添加到Project

我们在此讨论的任何示例都需要数据库连接。 让我们考虑MySQL数据库进行数据库操作。 它需要mysql-connector jar与Java程序交互。

按照步骤在项目中配置数据库jar。

  • 转到项目属性-》右键单击-》 Java构建路径-》 。 您将看到一个对话框,如下面的屏幕截图所示。 单击Add External Jars。

    外部罐子
  • 转到系统内存中的jar位置,选择文件并单击“打开”。

    Jar位置
  • 单击属性对话框上的确定。 您将获得MySQL连接器Jar到您的项目中。 现在您可以使用MySQL进行数据库操作。

JPA - Entity Managers

本章使用一个简单的示例来演示JPA的工作原理。 让我们以员工管理为例。 假设Employee Management创建,更新,查找和删除员工的记录。 如上所述,我们使用MySQL数据库进行数据库操作。

此示例的主要模块如下:

  • Model or POJO

    Employee.java

  • Persistence

    Persistence.xml

  • Service

    CreatingEmployee.java

    UpdatingEmployee.java

    FindingEmployee.java

    DeletingEmployee.java

让我们使用Eclipselink获取我们在JPA安装中使用的包层次结构。 遵循此示例的层次结构,如下所示:

包层次结构

创建实体

实体只是豆类或模型。 在此示例中,我们将使用Employee作为实体。 eidenamesalarydeg是该实体的属性。 它包含默认构造函数以及这些属性的setter和getter方法。

在上面显示的层次结构中,在'src' (Source)包下创建一个名为'com.iowiki.eclipselink.entity'包。 在给定的包下创建一个名为Employee.java的类,如下所示:

package com.iowiki.eclipselink.entity;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table
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 + "]";
	}
}

在上面的代码中,我们使用@Entity批注使这个POJO类成为一个实体。

在进入下一个模块之前,我们需要为关系实体创建数据库,该数据库将在persistence.xml文件中注册数据库。 打开MySQL工作台并在查询后输入hte。

create database jpadb
use jpadb

Persistence.xml

该模块在JPA的概念中起着至关重要的作用。 在这个xml文件中,我们将注册数据库并指定实体类。

在上面显示的包层次结构中,JPA Content包下的persistence.xml如下:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
	<persistence-unit name="Eclipselink_JPA" 
                        transaction-type="RESOURCE_LOCAL">
                         	<class>com.iowiki.eclipselink.entity.Employee</class>
	<properties>
	   <property name="javax.persistence.jdbc.url"
                   value="jdbc:mysql://localhost:3306/jpadb"/>
     	   <property name="javax.persistence.jdbc.user" value="root"/>
	       <property name="javax.persistence.jdbc.password" value="root"/>
	       <property name="javax.persistence.jdbc.driver"
                   value="com.mysql.jdbc.Driver"/>
           <property name="eclipselink.logging.level" value="FINE"/>
	       <property name="eclipselink.ddl-generation" 
		           value="create-tables"/>
	</properties>
	</persistence-unit>
</persistence>

在上面的xml中, 《persistence-unit》标签定义了JPA持久性的特定名称。 《class》标签定义具有包名称的实体类。 《properties》标签定义所有属性, 《property》标签定义每个属性,例如数据库注册,URL规范,用户名和密码。 这些是Eclipselink属性。 该文件将配置数据库。

持久性操作

持久性操作用于与数据库交互,它们是loadstore操作。 在业务组件中,所有持久性操作都属于服务类。

在上面显示的包层次结构中,在'src' (source)包下创建一个名为'com.iowiki.eclipselink.service'包。 所有服务类都命名为CreateEmloyee.java,UpdateEmployee.java,FindEmployee.java和DeleteEmployee.java。 在给定的包下面如下:

创建员工

以下代码段显示了如何创建名为CreateEmployee.java的Employee类。

package com.iowiki.eclipselink.service;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import com.iowiki.eclipselink.entity.Employee;
public class CreateEmployee 
{
	public static void main( String[ ] args ) 
	{
		EntityManagerFactory emfactory = Persistence.
				createEntityManagerFactory( "Eclipselink_JPA" );
		EntityManager entitymanager = emfactory.
				createEntityManager( );
		entitymanager.getTransaction( ).begin( );
		Employee employee = new Employee( ); 
		employee.setEid( 1201 );
		employee.setEname( "Gopal" );
		employee.setSalary( 40000 );
		employee.setDeg( "Technical Manager" );
		entitymanager.persist( employee );
		entitymanager.getTransaction( ).commit( );
		entitymanager.close( );
		emfactory.close( );
	}
}

在上面的代码中, createEntityManagerFactory ()通过提供我们在persistent.xml文件中为持久性单元提供的相同唯一名称来创建持久性单元。 entitymanagerfactory对象将使用createEntityManager ()方法创建entitymanger实例。 entitymanager对象为事务管理创建entitytransaction实例。 通过使用entitymanager对象,我们可以将实体持久化到数据库中。

编译和执行上述程序后,您将从eclipse IDE的控制台面板上的eclipselink库获得通知。

为此,打开MySQL工作台并键入以下查询。

use jpadb
select * from employee

名为employee的受影响数据库表将以表格格式显示,如下所示:

开斋节 易名 薪水 DEG
1201Gopal40000 技术经理

更新员工

要更新员工的记录,我们需要从数据库中检索现有记录,进行更改,最后将其提交到数据库。 名为UpdateEmployee.java的类如下所示:

package com.iowiki.eclipselink.service;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import com.iowiki.eclipselink.entity.Employee;
public class UpdateEmployee 
{
	public static void main( String[ ] args ) 
	{
		EntityManagerFactory emfactory = Persistence.
				createEntityManagerFactory( "Eclipselink_JPA" );
		EntityManager entitymanager = emfactory.
				createEntityManager( );
				entitymanager.getTransaction( ).begin( );
		Employee employee=entitymanager.
				find( Employee.class, 1201 );
		//before update
		System.out.println( employee );
		employee.setSalary( 46000 );
		entitymanager.getTransaction( ).commit( );
        //after update
		System.out.println( employee );
		entitymanager.close();
		emfactory.close();
	}
}

编译和执行上述程序后,您将从eclipse IDE的控制台面板上的Eclipselink库获得通知。

为此,打开MySQL工作台并键入以下查询。

use jpadb
select * from employee

名为employee的受影响数据库表将以表格格式显示,如下所示:

开斋节 易名 薪水 DEG
1201Gopal46000 技术经理

员工1201的工资更新为46000。

找到员工

要查找员工的记录,我们必须从数据库中检索现有数据并显示它。 在此操作中,检索记录时不应用EntityTransaction。

名为FindEmployee.java的类如下所示。

package com.iowiki.eclipselink.service;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import com.iowiki.eclipselink.entity.Employee;
public class FindEmployee 
{
	public static void main( String[ ] args ) 
	{
		EntityManagerFactory emfactory = Persistence
				.createEntityManagerFactory( "Eclipselink_JPA" );
		EntityManager entitymanager = emfactory.
				createEntityManager();
		Employee employee = entitymanager.
				find( Employee.class, 1201 );
		System.out.println("employee ID = "+employee.getEid( ));
		System.out.println("employee NAME = "+employee.getEname( ));
		System.out.println("employee SALARY = "+employee.getSalary( ));
		System.out.println("employee DESIGNATION = "+employee.getDeg( ));
	}
}

编译并执行上述程序后,您将从eclipse IDE的控制台面板上的Eclipselink库中获得以下输出。

employee ID = 1201
employee NAME = Gopal
employee SALARY = 46000.0
employee DESIGNATION = Technical Manager

删除员工

要删除员工的记录,首先我们将找到现有记录,然后将其删除。 EntityTransaction在这里发挥着重要作用。

名为DeleteEmployee.java的类如下:

package com.iowiki.eclipselink.service;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import com.iowiki.eclipselink.entity.Employee;
public class DeleteEmployee 
{
	public static void main( String[ ] args ) 
	{
		EntityManagerFactory emfactory = Persistence.
				createEntityManagerFactory( "Eclipselink_JPA" );
		EntityManager entitymanager = emfactory.
				createEntityManager( );
		entitymanager.getTransaction( ).begin( );
		Employee employee=entitymanager.
				find( Employee.class, 1201 );
		entitymanager.remove( employee );
		entitymanager.getTransaction( ).commit( );
		entitymanager.close( );
		emfactory.close( );
	}
}

编译和执行上述程序后,您将从eclipse IDE的控制台面板上的Eclipselink库获得通知。

为此,打开MySQL工作台并键入以下查询。

use jpadb
select * from employee

名为employee的受影响数据库将具有空记录。

完成此示例中的所有模块后,包和文件层次结构如下所示:

模块

JPA - JPQL

本章介绍了JPQL及其如何与持久性单元一起使用。 在本章中,给出的示例遵循我们在前一章中使用的相同的包层次结构。

JPA JPQL

Java持久性查询语言

JPQL代表Java持久性查询语言。 它用于创建针对要存储在关系数据库中的实体的查询。 JPQL是基于SQL语法开发的。 但它不会直接影响数据库。

JPQL可以使用SELECT子句检索数据,可以使用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 ...]

标量函数和聚合函数 (calar and Aggregate Functions)

标量函数根据输入值返回结果值。 聚合函数通过计算输入值来返回结果值。

我们将使用与前一章相同的Employee Management示例。 在这里,我们将使用JPQL的标量和聚合函数来检查服务类。

我们假设jpadb.employee表包含以下记录。

开斋节 易名 薪水 DEG
1201Gopal40000 技术经理
1202Manisha40000 证明读者
1203Masthanvali40000 技术文件撰稿人
1204Satish30000 技术文件撰稿人
1205Krishna30000 技术文件撰稿人
1206Kiran35000 证明读者

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

package com.iowiki.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
ax Employee Salary :40000.0

之间,和,像关键字

BetweenAndLike是JPQL的主要关键字。 这些关键字在查询中的Where clause之后使用。

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

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

Ordering

要在JPQL中订购记录,我们使用ORDER BY子句。 此子句的用法与SQL中的相同,但它处理实体。 以下示例显示如何使用ORDER BY子句。

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

package com.iowiki.eclipselink.service;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.Query;
import com.iowiki.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批注定义为具有不可更改的预定义查询字符串的查询。 与动态查询相比,命名查询可以通过将JPQL查询字符串与POJO分开来改进代码组织。 它还传递查询参数,而不是将文字动态嵌入到查询字符串中,从而产生更有效的查询。

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

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

package com.iowiki.eclipselink.service;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.Query;
import com.iowiki.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方法,则它将获取所有记录。

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

JPA - Advanced Mappings

JPA是一个随Java规范发布的库。 因此,它支持实体持久性的所有面向对象的概念。 到目前为止,我们已经完成了对象关系映射的基础知识。 本章将指导您完成对象和关系实体之间的高级映射。

继承策略

继承是任何面向对象语言的核心概念,因此我们可以使用实体之间的继承关系或策略。 JPA支持三种类型的继承策略:SINGLE_TABLE,JOINED_TABLE和TABLE_PER_CONCRETE_CLASS。

让我们考虑一个例子。 下图显示了三个类,即。 员工,TeachingStaff和NonTeachingStaff,以及他们的关系。

继承战略

在上图中,Staff是一个实体,而TeachingStaff和NonTeachingStaff是Staff的子实体。 这里我们将使用上面的例子来演示所有三种继承策略。

单表策略

单表策略采用所有类字段(超类和子类)并将它们映射到一个称为SINGLE_TABLE策略的表中。 这里,鉴别器值在区分一个表中三个实体的值方面起着关键作用。

让我们考虑上面的例子。 TeachingStaff和NonTeachingStaff是Staff的子类。 根据继承的概念,子类继承其超类的属性。 因此,sid和sname是属于TeachingStaff和NonTeachingStaff的字段。 创建一个JPA项目。 该项目的所有模块如下:

创建实体

'src'包下创建一个名为'com.iowiki.eclipselink.entity' 'src'包。 在给定的包下创建一个名为Staff.java的新java类。 Staff实体类如下所示:

package com.iowiki.eclipselink.entity;
import java.io.Serializable;
import javax.persistence.DiscriminatorColumn;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.Table;
@Entity
@Table
@Inheritance( strategy = InheritanceType.SINGLE_TABLE )
@DiscriminatorColumn( name="type" )
public class Staff implements Serializable 
{
	@Id
	@GeneratedValue( strategy = GenerationType.AUTO )
	private int sid;
	private String sname;
	public Staff( int sid, String sname ) 
	{
		super( );
		this.sid = sid;
		this.sname = sname;
	}
	public Staff( ) 
	{
		super( );
	}
	public int getSid( ) 
	{
		return sid;
	}
	public void setSid( int sid ) 
	{
		this.sid = sid;
	}
	public String getSname( ) 
	{
		return sname;
	}
	public void setSname( String sname ) 
	{
		this.sname = sname;
	}
}

在上面的代码中, @DescriminatorColumn指定字段名称(type) ,其值显示剩余的(Teaching和NonTeachingStaff)字段。

com.iowiki.eclipselink.entity包下创建名为TeachingStaff.java Staff类的子类(类)。 TeachingStaff Entity类如下所示:

package com.iowiki.eclipselink.entity;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
@Entity
@DiscriminatorValue( value="TS" )
public class TeachingStaff extends Staff 
{
	private String qualification;
	private String subjectexpertise;
	public TeachingStaff( int sid, String sname, 
			String qualification,String subjectexpertise ) 
	{
		super( sid, sname );
		this.qualification = qualification;
		this.subjectexpertise = subjectexpertise;
	}
	public TeachingStaff( ) 
	{
		super( );
	}
	public String getQualification( )
	{
		return qualification;
	}
	public void setQualification( String qualification )
	{
		this.qualification = qualification;
	}
	public String getSubjectexpertise( ) 
	{
		return subjectexpertise;
	}
	public void setSubjectexpertise( String subjectexpertise )
	{
		this.subjectexpertise = subjectexpertise;
	}
}

com.iowiki.eclipselink.entity包下创建名为NonTeachingStaff.java Staff类的子类(类)。 NonTeachingStaff Entity类如下所示:

package com.iowiki.eclipselink.entity;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
@Entity
@DiscriminatorValue( value = "NS" )
public class NonTeachingStaff extends Staff 
{
	private String areaexpertise;
	public NonTeachingStaff( int sid, String sname, 
			String areaexpertise ) 
	{
		super( sid, sname );
		this.areaexpertise = areaexpertise;
	}
	public NonTeachingStaff( ) 
	{
		super( );
	}
	public String getAreaexpertise( ) 
	{
		return areaexpertise;
	}
	public void setAreaexpertise( String areaexpertise )
	{
		this.areaexpertise = areaexpertise;
	}
}

Persistence.xml

Persistence.xml包含数据库的配置信息和实体类的注册信息。 xml文件如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
	<persistence-unit name="Eclipselink_JPA" 
                        transaction-type="RESOURCE_LOCAL">
	    <class>com.iowiki.eclipselink.entity.Staff</class>
		<class>com.iowiki.eclipselink.entity.NonTeachingStaff</class>
		<class>com.iowiki.eclipselink.entity.TeachingStaff</class>
		<properties>
			<property name="javax.persistence.jdbc.url" 
                            value="jdbc:mysql://localhost:3306/jpadb"/>
			<property name="javax.persistence.jdbc.user" value="root"/>
			<property name="javax.persistence.jdbc.password" 
                            value="root"/>
			<property name="javax.persistence.jdbc.driver" 
                            value="com.mysql.jdbc.Driver"/>
			<property name="eclipselink.logging.level" value="FINE"/>
			<property name="eclipselink.ddl-generation" 
                            value="create-tables"/>
		</properties>
	</persistence-unit>
</persistence>

服务类

服务类是业务组件的实现部分。 在'src'包下创建一个名为'com.iowiki.eclipselink.service' 'src'包。

在给定包下创建一个名为SaveClient.java的类,以存储Staff,TeachingStaff和NonTeachingStaff类字段。 SaveClient类如下所示:

package com.iowiki.eclipselink.service;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import com.iowiki.eclipselink.entity.NonTeachingStaff;
import com.iowiki.eclipselink.entity.TeachingStaff;
public class SaveClient 
{
	public static void main( String[ ] args ) 
	{
		EntityManagerFactory emfactory = Persistence.
				createEntityManagerFactory( "Eclipselink_JPA" );
		EntityManager entitymanager = emfactory.
				createEntityManager( );
		entitymanager.getTransaction( ).begin( );
		//Teaching staff entity 
		TeachingStaff ts1=new TeachingStaff(
				1,"Gopal","MSc MEd","Maths");
		TeachingStaff ts2=new TeachingStaff(
				2, "Manisha", "BSc BEd", "English");
		//Non-Teaching Staff entity
		NonTeachingStaff nts1=new NonTeachingStaff(
				3, "Satish", "Accounts");
		NonTeachingStaff nts2=new NonTeachingStaff(
				4, "Krishna", "Office Admin");
		//storing all entities
		entitymanager.persist(ts1);
		entitymanager.persist(ts2);
		entitymanager.persist(nts1);
		entitymanager.persist(nts2);
		entitymanager.getTransaction().commit();
		entitymanager.close();
		emfactory.close();
	}
}

编译并执行上述程序后,您将在Eclipse IDE的控制台面板上收到通知。 检查MySQL工作台的输出。 表格格式的输出如下所示:

希德 类型 SNAME Areaexpertise 合格 Subjectexpertise
1TSGopal MSC MED Maths
2TSManisha BSC BED English
3NSSatishAccounts
4NSKrishna 办公室管理员

最后,您将获得一个包含所有三个类的字段的表,其中一个名为Type (field)的鉴别器列。

加入表策略

连接表策略是共享包含唯一值的引用列以加入表并进行简单事务。 让我们考虑与上面相同的例子。

创建JPA项目。 所有项目模块如下所示。

创建实体 (Creating Entities)

'src'包下创建一个名为'com.iowiki.eclipselink.entity' 'src'包。 在给定的包下创建一个名为Staff.java的新java类。 Staff实体类如下所示:

package com.iowiki.eclipselink.entity;
import java.io.Serializable;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.Table;
@Entity
@Table
@Inheritance( strategy = InheritanceType.JOINED )
public class Staff implements Serializable 
{
	@Id
	@GeneratedValue( strategy = GenerationType.AUTO )
	private int sid;
	private String sname;
	public Staff( int sid, String sname ) 
	{
		super( );
		this.sid = sid;
		this.sname = sname;
	}
	public Staff( ) 
	{
		super( );
	}
	public int getSid( ) 
	{
		return sid;
	}
	public void setSid( int sid ) 
	{
		this.sid = sid;
	}
	public String getSname( ) 
	{
		return sname;
	}
	public void setSname( String sname ) 
	{
		this.sname = sname;
	}
}

com.iowiki.eclipselink.entity包下创建名为TeachingStaff.java Staff类的子类(类)。 TeachingStaff Entity类如下所示:

package com.iowiki.eclipselink.entity;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
@Entity
@PrimaryKeyJoinColumn(referencedColumnName="sid")
public class TeachingStaff extends Staff 
{
	private String qualification;
	private String subjectexpertise;
	public TeachingStaff( int sid, String sname, 
			String qualification,String subjectexpertise ) 
	{
		super( sid, sname );
		this.qualification = qualification;
		this.subjectexpertise = subjectexpertise;
	}
	public TeachingStaff( ) 
	{
		super( );
	}
	public String getQualification( )
	{
		return qualification;
	}
	public void setQualification( String qualification )
	{
		this.qualification = qualification;
	}
	public String getSubjectexpertise( ) 
	{
		return subjectexpertise;
	}
	public void setSubjectexpertise( String subjectexpertise )
	{
		this.subjectexpertise = subjectexpertise;
	}
}

com.iowiki.eclipselink.entity包下创建名为NonTeachingStaff.java Staff类的子类(类)。 NonTeachingStaff Entity类如下所示:

package com.iowiki.eclipselink.entity;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
@Entity
@PrimaryKeyJoinColumn(referencedColumnName="sid")
public class NonTeachingStaff extends Staff 
{
	private String areaexpertise;
	public NonTeachingStaff( int sid, String sname, 
			String areaexpertise ) 
	{
		super( sid, sname );
		this.areaexpertise = areaexpertise;
	}
	public NonTeachingStaff( ) 
	{
		super( );
	}
	public String getAreaexpertise( ) 
	{
		return areaexpertise;
	}
	public void setAreaexpertise( String areaexpertise )
	{
		this.areaexpertise = areaexpertise;
	}
}

Persistence.xml

Persistence.xml文件包含数据库的配置信息和实体类的注册信息。 xml文件如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
	<persistence-unit name="Eclipselink_JPA" 
                        transaction-type="RESOURCE_LOCAL">
	<class>com.iowiki.eclipselink.entity.Staff</class>
	<class>com.iowiki.eclipselink.entity.NonTeachingStaff</class>
	<class>com.iowiki.eclipselink.entity.TeachingStaff</class>
		<properties>
			<property name="javax.persistence.jdbc.url" 
                            value="jdbc:mysql://localhost:3306/jpadb"/>
			<property name="javax.persistence.jdbc.user" value="root"/>
			<property name="javax.persistence.jdbc.password" 
                            value="root"/>
			<property name="javax.persistence.jdbc.driver" 
                            value="com.mysql.jdbc.Driver"/>
			<property name="eclipselink.logging.level" value="FINE"/>
			<property name="eclipselink.ddl-generation" 
                            value="create-tables"/>
		</properties>
	</persistence-unit>
</persistence>

服务类

服务类是业务组件的实现部分。 在'src'包下创建一个名为'com.iowiki.eclipselink.service' 'src'包。

在给定包下创建一个名为SaveClient.java的类,以存储Staff,TeachingStaff和NonTeachingStaff类的字段。 然后SaveClient类如下所示:

package com.iowiki.eclipselink.service;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import com.iowiki.eclipselink.entity.NonTeachingStaff;
import com.iowiki.eclipselink.entity.TeachingStaff;
public class SaveClient 
{
	public static void main( String[ ] args ) 
	{
		EntityManagerFactory emfactory = Persistence.
				createEntityManagerFactory( "Eclipselink_JPA" );
		EntityManager entitymanager = emfactory.
				createEntityManager( );
		entitymanager.getTransaction( ).begin( );
		//Teaching staff entity 
		TeachingStaff ts1=new TeachingStaff(
				1,"Gopal","MSc MEd","Maths");
		TeachingStaff ts2=new TeachingStaff(
				2, "Manisha", "BSc BEd", "English");
		//Non-Teaching Staff entity
		NonTeachingStaff nts1=new NonTeachingStaff(
				3, "Satish", "Accounts");
		NonTeachingStaff nts2=new NonTeachingStaff(
		4, "Krishna", "Office Admin");
		//storing all entities
		entitymanager.persist(ts1);
		entitymanager.persist(ts2);
		entitymanager.persist(nts1);
		entitymanager.persist(nts2);
		entitymanager.getTransaction().commit();
		entitymanager.close();
		emfactory.close();
	}
}

编译并执行上述程序后,您将在Eclipse IDE的控制台面板中收到通知。 对于输出,请检查MySQL工作台。

这里创建了三个表, staff表的结果以表格格式显示。

希德 D型 SNAME
1TeachingStaffGopal
2TeachingStaffManisha
3NonTeachingStaffSatish
4NonTeachingStaffKrishna

TeachingStaff表的结果显示如下:

希德 合格 Subjectexpertise
1 MSC MED Maths
2 BSC BED English

在上面的表中,sid是外键(引用字段表格staff表) NonTeachingStaff表的结果显示如下:

希德 Areaexpertise
3Accounts
4 办公室管理员

最后,使用各自的字段创建三个表,并且所有三个表共享SID字段。 在Staff表中,SID是主键。 在剩余的两个表(TeachingStaff和NonTeachingStaff)中,SID是外键。

每班策略表

每类策略的表是为每个子实体创建一个表。 将创建Staff表,但它将包含空值。 Staff表的字段值必须由TeachingStaff和NonTeachingStaff表共享。

让我们考虑与上面相同的例子。

创建实体 (Creating Entities)

'src'包下创建一个名为'com.iowiki.eclipselink.entity' 'src'包。 在给定的包下创建一个名为Staff.java的新java类。 Staff实体类如下所示:

package com.iowiki.eclipselink.entity;
import java.io.Serializable;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.Table;
@Entity
@Table
@Inheritance( strategy = InheritanceType.TABLE_PER_CLASS )
public class Staff implements Serializable 
{
	@Id
	@GeneratedValue( strategy = GenerationType.AUTO )
	private int sid;
	private String sname;
	public Staff( int sid, String sname ) 
	{
		super( );
		this.sid = sid;
		this.sname = sname;
	}
	public Staff( ) 
	{
		super( );
	}
	public int getSid( ) 
	{
		return sid;
	}
	public void setSid( int sid ) 
	{
		this.sid = sid;
	}
	public String getSname( ) 
	{
		return sname;
	}
	public void setSname( String sname ) 
	{
		this.sname = sname;
	}
}

com.iowiki.eclipselink.entity包下创建名为TeachingStaff.java Staff类的子类(类)。 TeachingStaff Entity类如下所示:

package com.iowiki.eclipselink.entity;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
@Entity
public class TeachingStaff extends Staff 
{
	private String qualification;
	private String subjectexpertise;
	public TeachingStaff( int sid, String sname, 
			String qualification,String subjectexpertise ) 
	{
		super( sid, sname );
		this.qualification = qualification;
		this.subjectexpertise = subjectexpertise;
	}
	public TeachingStaff( ) 
	{
		super( );
	}
	public String getQualification( )
	{
		return qualification;
	}
	public void setQualification( String qualification )
	{
		this.qualification = qualification;
	}
	public String getSubjectexpertise( ) 
	{
		return subjectexpertise;
	}
	public void setSubjectexpertise( String subjectexpertise )
	{
		this.subjectexpertise = subjectexpertise;
	}
}

com.iowiki.eclipselink.entity包下创建名为NonTeachingStaff.java Staff类的子类(类)。 NonTeachingStaff Entity类如下所示:

package com.iowiki.eclipselink.entity;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
@Entity
public class NonTeachingStaff extends Staff 
{
	private String areaexpertise;
	public NonTeachingStaff( int sid, String sname, 
			String areaexpertise )
			{
		super( sid, sname );
		this.areaexpertise = areaexpertise;
	}
	public NonTeachingStaff( ) 
	{
		super( );
	}
	public String getAreaexpertise( ) 
	{
		return areaexpertise;
	}
	public void setAreaexpertise( String areaexpertise )
	{
		this.areaexpertise = areaexpertise;
	}
}

Persistence.xml

Persistence.xml文件包含数据库的配置信息和实体类的注册信息。 xml文件如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
	<persistence-unit name="Eclipselink_JPA" 
                        transaction-type="RESOURCE_LOCAL">
	<class>com.iowiki.eclipselink.entity.Staff</class>
	<class>com.iowiki.eclipselink.entity.NonTeachingStaff</class>
	<class>com.iowiki.eclipselink.entity.TeachingStaff</class>
		<properties>
			<property name="javax.persistence.jdbc.url" 
                            value="jdbc:mysql://localhost:3306/jpadb"/>
			<property name="javax.persistence.jdbc.user" value="root"/>
			<property name="javax.persistence.jdbc.password" 
                            value="root"/>
			<property name="javax.persistence.jdbc.driver" 
                            value="com.mysql.jdbc.Driver"/>
			<property name="eclipselink.logging.level" value="FINE"/>
			<property name="eclipselink.ddl-generation" 
                            value="create-tables"/>
			</properties>
	</persistence-unit>
</persistence>

服务类

服务类是业务组件的实现部分。 在'src'包下创建一个名为'com.iowiki.eclipselink.service' 'src'包。

在给定包下创建一个名为SaveClient.java的类,以存储Staff,TeachingStaff和NonTeachingStaff类字段。 SaveClient类如下所示:

package com.iowiki.eclipselink.service;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import com.iowiki.eclipselink.entity.NonTeachingStaff;
import com.iowiki.eclipselink.entity.TeachingStaff;
public class SaveClient 
{
	public static void main( String[ ] args ) 
	{
		EntityManagerFactory emfactory = Persistence.
				createEntityManagerFactory( "Eclipselink_JPA" );
		EntityManager entitymanager = emfactory.
				createEntityManager( );
		entitymanager.getTransaction( ).begin( );
		//Teaching staff entity 
		TeachingStaff ts1=new TeachingStaff(
				1,"Gopal","MSc MEd","Maths");
		TeachingStaff ts2=new TeachingStaff(
				2, "Manisha", "BSc BEd", "English");
		//Non-Teaching Staff entity
		NonTeachingStaff nts1=new NonTeachingStaff(
				3, "Satish", "Accounts");
		NonTeachingStaff nts2=new NonTeachingStaff(
				4, "Krishna", "Office Admin");
		//storing all entities
		entitymanager.persist(ts1);
		entitymanager.persist(ts2);
		entitymanager.persist(nts1);
		entitymanager.persist(nts2);
		entitymanager.getTransaction().commit();
		entitymanager.close();
		emfactory.close();
	}
}

编译并执行上述程序后,您将在Eclipse IDE的控制台面板上收到通知。 对于输出,请检查MySQL工作台。

这里创建了三个表, Staff表包含空记录。

TeachingStaff的结果显示如下:

希德 合格 SNAME Subjectexpertise
1 MSC MED GopalMaths
2 BSC BED ManishaEnglish

上表TeachingStaff包含Staff和TeachingStaff实体的字段。

NonTeachingStaff的结果显示如下:

希德 Areaexpertise SNAME
3AccountsSatish
4 办公室管理员 Krishna

上表NonTeachingStaff包含Staff和NonTeachingStaff实体的字段。

JPA - Entity Relationships

本章将向您介绍实体之间的关系。 通常,关系在数据库中的表之间更有效。 这里实体类被视为关系表(JPA的概念),因此实体类之间的关系如下:

  • @ManyToOne关系
  • @OneToMany关系
  • @OneToOne关系
  • @ManyToMany关系

@ManyToOne关系

实体之间存在多对一关系,其中一个实体(列或列集)与包含唯一值的另一个实体(列或列集)一起引用。 在关系数据库中,通过在表之间使用外键/主键来应用这些关系。

让我们考虑一下Employee和Department实体之间关系的一个例子。 以单向方式,即从员工到部门,多对一关系是适用的。 这意味着员工的每条记录都包含一个部门ID,该部门ID应该是Department表中的主键。 在Employee表中,Department id是外键。

下图显示了两个表之间的“多对一”关系。

@ManyToOne关系

在eclipse IDE中创建一个名为JPA_Eclipselink_MTO的JPA项目。 该项目的所有模块将在下面讨论。

创建实体 (Creating Entities)

按照上面给出的图表来创建实体。 在'src'包下创建一个名为'com.tutorialspoin.eclipselink.entity' 'src'包。 在给定的包下创建一个名为Department.java的类。 类Department实体如下所示:

package com.iowiki.eclipselink.entity;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
@Entity
public class Department 
{
    @Id 
    @GeneratedValue( strategy=GenerationType.AUTO )
    private int id;
    private String name;
    public int getId() 
    {
    	return id;
    }
    public void setId(int id) 
    {
    	this.id = id;
    }
    public String getName( )
    {
    	return name;
    }
    public void setName( String deptName )
    {
    	this.name = deptName;
    }
}

在此关系中创建第二个实体 - 名为Employee.java Employee实体类位于'com.iowiki.eclipselink.entity'包下。 Employee实体类如下所示:

package com.iowiki.eclipselink.entity;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
@Entity
public class Employee 
{
	@Id
	@GeneratedValue( strategy= GenerationType.AUTO ) 	
	private int eid;
	private String ename;
	private double salary;
	private String deg;
	@ManyToOne
	private Department department;
	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;
	}
	public Department getDepartment() {
		return department;
	}
	public void setDepartment(Department department) {
		this.department = department;
	}
}

Persistence.xml

需要Persistence.xml文件来配置数据库和实体类的注册。

在创建JPA项目时,eclipse IDE将创建Persitence.xml。 配置详细信息是用户规范。 persistence.xml文件如下所示:


<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" 
             xmlns="http://java.sun.com/xml/ns/persistence" 
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
             xsi:schemaLocation="http://java.sun.com/xml/ns/persistence 
             http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
	<persistence-unit name="Eclipselink_JPA" 
                        transaction-type="RESOURCE_LOCAL">
	<class>com.iowiki.eclipselink.entity.Employee</class>
	<class>com.iowiki.eclipselink.entity.Department</class>
		<properties>
			<property name="javax.persistence.jdbc.url" 
			          value="jdbc:mysql://localhost:3306/jpadb"/>
			<property name="javax.persistence.jdbc.user" value="root"/>
			<property name="javax.persistence.jdbc.password"
                            value="root"/>
			<property name="javax.persistence.jdbc.driver" 
			          value="com.mysql.jdbc.Driver"/>
			<property name="eclipselink.logging.level" value="FINE"/>
			<property name="eclipselink.ddl-generation" 
			          value="create-tables"/>
		</properties>
	</persistence-unit>
</persistence>

服务类

此模块包含服务类,它使用属性初始化实现关系部分。 在'src'包下创建一个名为'com.iowiki.eclipselink.service' 'src'包。 在给定包下创建名为ManyToOne.java的DAO类。 DAO类如下所示:

package com.iowikieclipselink.service;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import com.iowiki.eclipselink.entity.Department;
import com.iowiki.eclipselink.entity.Employee;
public class ManyToOne 
{
	public static void main( String[ ] args ) 
	{
		EntityManagerFactory emfactory = Persistence.
				createEntityManagerFactory( "Eclipselink_JPA" );
		EntityManager entitymanager = emfactory.
				createEntityManager( );
		entitymanager.getTransaction( ).begin( );
		//Create Department Entity
		Department department = new Department();
		department.setName("Development");
		//Store Department
		entitymanager.persist(department);
		//Create Employee1 Entity
		Employee employee1 = new Employee();
		employee1.setEname("Satish");
		employee1.setSalary(45000.0);
		employee1.setDeg("Technical Writer");
		employee1.setDepartment(department);
		//Create Employee2 Entity
		Employee employee2 = new Employee();
		employee2.setEname("Krishna");
		employee2.setSalary(45000.0);
		employee2.setDeg("Technical Writer");
		employee2.setDepartment(department);
		//Create Employee3 Entity
		Employee employee3 = new Employee();
		employee3.setEname("Masthanvali");
		employee3.setSalary(50000.0);
		employee3.setDeg("Technical Writer");
		employee3.setDepartment(department);
		//Store Employees
		entitymanager.persist(employee1);
		entitymanager.persist(employee2);
		entitymanager.persist(employee3);
		entitymanager.getTransaction().commit();
		entitymanager.close();
		emfactory.close();
	}
}

编译并执行上述程序后,您将在Eclipse IDE的控制台面板上收到通知。 对于输出,请检查MySQL工作台。 在此示例中,创建了两个表。

在MySQL界面中传递以下查询, Department表的结果将显示如下:

Select * from department
ID 名称
101Development

在MySQL界面中传递以下查询, Employee表的结果将显示如下。

Select * from employee
开斋节 DEG 易名 薪水 DEPARTMENT_ID
102 技术文件撰稿人 Satish45000101
103 技术文件撰稿人 Krishna45000101
104 技术文件撰稿人 Masthanwali50000101

在上表中,Deparment_Id是Department表中的外键(引用字段)。

@OneToMany关系

在此关系中,一个实体的每一行都引用其他实体中的许多子记录。 重要的是,儿童记录不能有多个父母。 在表A和表B之间的一对多关系中,表A中的每一行可以链接到表B中的一行或多行。

让我们考虑上面的例子。 假设上例中的Employee和Department表以反向单向方式连接,则该关系变为One-To-Many关系。 在eclipse IDE中创建一个名为JPA_Eclipselink_OTM的JPA项目。 该项目的所有模块将在下面讨论。

创建实体 (Creating Entities)

按照上面给出的图表来创建实体。 在'src'包下创建一个名为'com.tutorialspoin.eclipselink.entity' 'src'包。 在给定的包下创建一个名为Department.java的类。 类Department实体如下所示:

package com.iowiki.eclipselink.entity;
import java.util.List;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
@Entity
public class Department 
{
    @Id 
    @GeneratedValue( strategy=GenerationType.AUTO )
    private int id;
    private String name;
    @OneToMany( targetEntity=Employee.class )
    private List employeelist;
    public int getId() 
    {
    	return id;
    }
    public void setId(int id) 
    {
    	this.id = id;
    }
    public String getName( )
    {
    	return name;
    }
    public void setName( String deptName )
    {
    	this.name = deptName;
    }
    public List getEmployeelist() 
    {
	return employeelist;
    }
    public void setEmployeelist(List employeelist) 
    {
	this.employeelist = employeelist;
    }
}

在此关系中创建第二个实体'com.iowiki.eclipselink.entity'实体类,名为Employee.java位于'com.iowiki.eclipselink.entity'包下。 Employee实体类如下所示:

package com.iowiki.eclipselink.entity;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
@Entity
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;
	}	
}

Persistence.xml

persistence.xml文件如下:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" 
             xmlns="http://java.sun.com/xml/ns/persistence" 
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
             xsi:schemaLocation="http://java.sun.com/xml/ns/persistence 
             http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
	<persistence-unit name="Eclipselink_JPA" 
                        transaction-type="RESOURCE_LOCAL">
	<class>com.iowiki.eclipselink.entity.Employee</class>
	<class>com.iowiki.eclipselink.entity.Department</class>
		<properties>
			<property name="javax.persistence.jdbc.url" 
			          value="jdbc:mysql://localhost:3306/jpadb"/>
			<property name="javax.persistence.jdbc.user" value="root"/>
			<property name="javax.persistence.jdbc.password" 
                            value="root"/>
			<property name="javax.persistence.jdbc.driver" 
			          value="com.mysql.jdbc.Driver"/>
			<property name="eclipselink.logging.level" value="FINE"/>
			<property name="eclipselink.ddl-generation" 
			          value="create-tables"/>
		</properties>
	</persistence-unit>
</persistence>

服务类

此模块包含服务类,它使用属性初始化实现关系部分。 在'src'包下创建一个名为'com.iowiki.eclipselink.service' 'src'包。 名为OneToMany.java的DAO类是在给定包下创建的。 DAO类如下所示:

package com.iowikieclipselink.service;
import java.util.List;
import java.util.ArrayList;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import com.iowiki.eclipselink.entity.Department;
import com.iowiki.eclipselink.entity.Employee;
public class OneToMany 
{
	public static void main(String[] args) 
	{
		EntityManagerFactory emfactory = Persistence.
				createEntityManagerFactory( "Eclipselink_JPA" );
		EntityManager entitymanager = emfactory.
				createEntityManager( );
		entitymanager.getTransaction( ).begin( );
		//Create Employee1 Entity
		Employee employee1 = new Employee();
		employee1.setEname("Satish");
		employee1.setSalary(45000.0);
		employee1.setDeg("Technical Writer");
		//Create Employee2 Entity
		Employee employee2 = new Employee();
		employee2.setEname("Krishna");
		employee2.setSalary(45000.0);
		employee2.setDeg("Technical Writer");
		//Create Employee3 Entity
		Employee employee3 = new Employee();
		employee3.setEname("Masthanvali");
		employee3.setSalary(50000.0);
		employee3.setDeg("Technical Writer");
		//Store Employee
		entitymanager.persist(employee1);
		entitymanager.persist(employee2);
		entitymanager.persist(employee3);
		//Create Employeelist
		List<Employee> emplist = new ArrayList();
		emplist.add(employee1);
		emplist.add(employee2);
		emplist.add(employee3);
		//Create Department Entity
		Department department= new Department();
		department.setName("Development");
		department.setEmployeelist(emplist);
		//Store Department
		entitymanager.persist(department);
		entitymanager.getTransaction().commit();
		entitymanager.close();
		emfactory.close();
	}
}

编译和执行上述程序后,您将在Eclipse IDE的控制台面板中收到通知。 对于输出检查MySQL工作台如下。

在这个项目中,创建了三个表。 在MySQL界面中传递以下查询,department_employee表的结果将显示如下:

Select * from department_Id;
部门编号 Employee_Eid
254251
254252
254253

在上表中, deparment_idemployee_id是来自department和employee表的外键(引用字段)。

在MySQL界面中传递以下查询,部门表的结果将以表格格式显示如下。

Select * from department;
ID 名称
254Development

在MySQL界面中传递以下查询,employee表的结果将显示如下:

Select * from employee;
开斋节 DEG 易名 薪水
251 技术文件撰稿人 Satish45000
252 技术文件撰稿人 Krishna45000
253 技术文件撰稿人 Masthanwali50000

@OneToOne关系

在一对一关系中,一个项目只能链接到另一个项目。 这意味着一个实体的每一行被称为另一个实体的一行且仅一行。

让我们考虑上面的例子。 EmployeeDepartment以反向单向的方式,关系是一对一的关系。 这意味着每个员工只属于一个部门。 在eclipse IDE中创建一个名为JPA_Eclipselink_OTO的JPA项目。 该项目的所有模块将在下面讨论。

创建实体 (Creating Entities)

按照上面给出的图表来创建实体。 在'src'包下创建一个名为'com.tutorialspoin.eclipselink.entity' 'src'包。 在给定的包下创建一个名为Department.java的类。 类Department实体如下所示:

package com.iowiki.eclipselink.entity;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
@Entity
public class Department 
{
    @Id 
    @GeneratedValue( strategy=GenerationType.AUTO )
    private int id;
    private String name;
    public int getId() 
    {
    	return id;
    }
    public void setId(int id) 
    {
    	this.id = id;
    }
    public String getName( )
    {
    	return name;
    }
    public void setName( String deptName )
    {
    	this.name = deptName;
    }
}

在此关系中创建第二个实体'com.iowiki.eclipselink.entity'实体类,名为Employee.java位于'com.iowiki.eclipselink.entity'包下。 Employee实体类如下所示:

package com.iowiki.eclipselink.entity;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToOne;
@Entity
public class Employee 
{
	@Id
	@GeneratedValue( strategy= GenerationType.AUTO ) 	
	private int eid;
	private String ename;
	private double salary;
	private String deg;
	@OneToOne
	private Department department;
	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;
	}
	public Department getDepartment() 
	{
		return department;
	}
	public void setDepartment(Department department) 
	{
		this.department = department;
	}	
}

Persistence.xml

Persistence.xml文件如下:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" 
             xmlns="http://java.sun.com/xml/ns/persistence" 
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
             xsi:schemaLocation="http://java.sun.com/xml/ns/persistence 
             http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
	<persistence-unit name="Eclipselink_JPA" 
                        transaction-type="RESOURCE_LOCAL">
	<class>com.iowiki.eclipselink.entity.Employee</class>
	<class>com.iowiki.eclipselink.entity.Department</class>
		<properties>
			<property name="javax.persistence.jdbc.url" 
			          value="jdbc:mysql://localhost:3306/jpadb"/>
			<property name="javax.persistence.jdbc.user" value="root"/>
			<property name="javax.persistence.jdbc.password" 
                            value="root"/>
			<property name="javax.persistence.jdbc.driver" 
			          value="com.mysql.jdbc.Driver"/>
			<property name="eclipselink.logging.level" value="FINE"/>
			<property name="eclipselink.ddl-generation" 
			          value="create-tables"/>
		</properties>
	</persistence-unit>
</persistence>

服务类

'src'包下创建一个名为'com.iowiki.eclipselink.service' 'src'包。 名为OneToOne.java的DAO类是在给定包下创建的。 DAO类如下所示:

package com.iowikieclipselink.service;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import com.iowiki.eclipselink.entity.Department;
import com.iowiki.eclipselink.entity.Employee;
public class OneToOne 
{
	public static void main(String[] args) 
	{
		EntityManagerFactory emfactory = Persistence.
				createEntityManagerFactory( "Eclipselink_JPA" );
		EntityManager entitymanager = emfactory.
				createEntityManager( );
		entitymanager.getTransaction( ).begin( );
		//Create Department Entity
		Department department = new Department();
		department.setName("Development");
		//Store Department
		entitymanager.persist(department);
		//Create Employee Entity
		Employee employee = new Employee();
		employee.setEname("Satish");
		employee.setSalary(45000.0);
		employee.setDeg("Technical Writer");
		employee.setDepartment(department);
		//Store Employee
		entitymanager.persist(employee);
		entitymanager.getTransaction().commit();
		entitymanager.close();
		emfactory.close();
	}
}

编译和执行上述程序后,您将在Eclipse IDE的控制台面板中收到通知。 对于输出,请按如下方式检查MySQL工作台。

在上面的示例中,创建了两个表。 在MySQL界面中传递以下查询,部门表的结果将显示如下:

Select * from department
ID 名称
301Development

在MySQL界面中传递以下查询, employee表的结果将显示如下:

Select * from employee
开斋节 DEG 易名 薪水 DEPARTMENT_ID
302 技术文件撰稿人 Satish45000301

@ManyToMany关系

多对多关系是来自一个实体的一个或多个行与其他实体中的多个行相关联的位置。

让我们考虑两个实体之间关系的一个例子: ClassTeacher 。 以双向方式,class和教师都有多对一的关系。 这意味着Class的每个记录都由Teacher set(teacher id)引用,它应该是Teacher表中的主键并存储在Teacher_Class表中,反之亦然。 这里,Teachers_Class表包含两个外键字段。 在eclipse IDE中创建一个名为JPA_Eclipselink_MTM的JPA项目。 该项目的所有模块将在下面讨论。

@ManyToOne关系

创建实体 (Creating Entities)

按照上图中显示的模式创建实体。 在'src'包下创建一个名为'com.tutorialspoin.eclipselink.entity' 'src'包。 在给定的包下创建一个名为Clas.java的类。 类Department实体如下所示:

package com.iowiki.eclipselink.entity;
import java.util.Set;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToMany;
@Entity
public class Clas 
{
	@Id
	@GeneratedValue( strategy = GenerationType.AUTO )
	private int cid;
	private String cname;
	@ManyToMany(targetEntity=Teacher.class)
	private Set teacherSet;
	public Clas() 
	{
		super();
	}
	public Clas(int cid, 
			String cname, Set teacherSet) 
	{
		super();
		this.cid = cid;
		this.cname = cname;
		this.teacherSet = teacherSet;
	}
	public int getCid() 
	{
		return cid;
	}
	public void setCid(int cid) 
	{
		this.cid = cid;
	}
	public String getCname() 
	{
		return cname;
	}
	public void setCname(String cname) 
	{
		this.cname = cname;
	}
	public Set getTeacherSet() 
	{
		return teacherSet;
	}
	public void setTeacherSet(Set teacherSet) 
	{
		this.teacherSet = teacherSet;
	}	  
}

在此关系中创建第二个实体Teacher.java实体类,名为Teacher.java位于'com.iowiki.eclipselink.entity'包下。 Employee实体类如下所示:

package com.iowiki.eclipselink.entity;
import java.util.Set;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToMany;
@Entity
public class Teacher 
{
	@Id
	@GeneratedValue( strategy = GenerationType.AUTO )
	private int tid;
	private String tname;
	private String subject;
	@ManyToMany(targetEntity=Clas.class)
	private Set clasSet;
	public Teacher() 
	{
		super();
	}
	public Teacher(int tid, String tname, String subject, 
			Set clasSet) 
	{
		super();
		this.tid = tid;
		this.tname = tname;
		this.subject = subject;
		this.clasSet = clasSet;
	}
	public int getTid() 
	{
		return tid;
	}
	public void setTid(int tid) 
	{
		this.tid = tid;
	}
	public String getTname() 
	{
		return tname;
	}
	public void setTname(String tname) 
	{
		this.tname = tname;
	}
	public String getSubject() 
	{
		return subject;
	}
	public void setSubject(String subject) 
	{
		this.subject = subject;
	}
	public Set getClasSet() 
	{
		return clasSet;
	}
	public void setClasSet(Set clasSet) 
	{
		this.clasSet = clasSet;
	}
}

Persistence.xml

Persistence.xml文件如下:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" 
             xmlns="http://java.sun.com/xml/ns/persistence" 
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
             xsi:schemaLocation="http://java.sun.com/xml/ns/persistence 
             http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
	<persistence-unit name="Eclipselink_JPA" 
                        transaction-type="RESOURCE_LOCAL">
	<class>com.iowiki.eclipselink.entity.Employee</class>
	<class>com.iowiki.eclipselink.entity.Department</class>
		<properties>
			<property name="javax.persistence.jdbc.url" 
			          value="jdbc:mysql://localhost:3306/jpadb"/>
			<property name="javax.persistence.jdbc.user" value="root"/>
			<property name="javax.persistence.jdbc.password" 
                            value="root"/>
			<property name="javax.persistence.jdbc.driver" 
			          value="com.mysql.jdbc.Driver"/>
			<property name="eclipselink.logging.level" value="FINE"/>
			<property name="eclipselink.ddl-generation" 
			          value="create-tables"/>
		</properties>
	</persistence-unit>
</persistence>

服务类

'src'包下创建一个名为'com.iowiki.eclipselink.service' 'src'包。 名为ManyToMany.java的DAO类是在给定包下创建的。 DAO类如下所示:

package com.iowiki.eclipselink.service;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import com.iowiki.eclipselink.entity.Clas;
import com.iowiki.eclipselink.entity.Teacher;
public class ManyToMany 
{
	public static void main(String[] args) 
	{
		EntityManagerFactory emfactory = Persistence.
				createEntityManagerFactory( "Eclipselink_JPA" );
		EntityManager entitymanager = emfactory.
				createEntityManager( );
		entitymanager.getTransaction( ).begin( );
		//Create Clas Entity
		Clas clas1=new Clas(0,"1st",null);
		Clas clas2=new Clas(0,"2nd",null);
		Clas clas3=new Clas(0,"3rd",null);
		//Store Clas
		entitymanager.persist(clas1);
		entitymanager.persist(clas2);
		entitymanager.persist(clas3);
		//Create Clas Set1
		Set<Clas> classSet1 = new HashSet();
		classSet1.add(clas1);
		classSet1.add(clas2);
		classSet1.add(clas3);
		//Create Clas Set2
		Set<Clas> classSet2 = new HashSet();
		classSet2.add(clas3);
		classSet2.add(clas1);
		classSet2.add(clas2);
		//Create Clas Set3
		Set<Clas> classSet3 = new HashSet();
		classSet3.add(clas2);
		classSet3.add(clas3);
		classSet3.add(clas1);
		//Create Teacher Entity
		Teacher teacher1 = new Teacher(0,
				"Satish","Java",classSet1);
		Teacher teacher2 = new Teacher(0,
				"Krishna","Adv Java",classSet2);
		Teacher teacher3 = new Teacher(0,
				"Masthanvali","DB2",classSet3);
		//Store Teacher
		entitymanager.persist(teacher1);
		entitymanager.persist(teacher2);
		entitymanager.persist(teacher3);
		entitymanager.getTransaction( ).commit( );
		entitymanager.close( );
		emfactory.close( );
	}
}

在此示例项目中,创建了三个表。 在MySQL界面中传递以下查询,teacher_clas表的结果将显示如下:

Select * form teacher_clas
Teacher_tid Classet_cid
354351
355351
356351
354352
355352
356352
354353
355353
356353

在上表中, classet_cid是来自teacher表的外键, classet_cid是来自类表的外键。 因此,不同的教师被分配到不同的class。

在MySQL界面中传递以下查询,教师表的结果将显示如下:

Select * from teacher
TID 学科 TNAME
354JavaSatish
355 Adv Java Krishna
356DB2Masthanvali

在MySQL界面中传递以下查询, clas表的结果将显示如下:

Select * from clas
CNAME
3511st
3522nd
3533rd

JPA - Criteria API

Criteria是一个预定义的API,用于定义实体的查询。 它是定义JPQL查询的另一种方法。 这些查询是类型安全的,可移植的,并且通过更改语法易于修改。 与JPQL类似,它遵循抽象模式(易于编辑模式)和嵌入对象。 元数据API与标准API混合以为标准查询建模持久实体。

Criteria API的主要优点是可以在编译期间更早地检测到错误。 基于字符串的JPQL查询和基于JPA标准的查询在性能和效率方面是相同的。

标准API的历史

该标准包含在JPA的所有版本中,因此标准的每个步骤都在JPA的规范中得到通知。

  • 在JPA 2.0中,开发了标准查询API,查询的标准化。
  • 在JPA 2.1中,包括Criteria更新和删除(批量更新和删除)。

标准查询结构

Criteria和JPQL密切相关,允许在查询中使用类似的运算符进行设计。 它遵循javax.persistence.criteria包来设计查询。 查询结构表示语法标准查询。

以下简单条件查询返回数据源中实体类的所有实例。

EntityManager em = ...;
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Entity class> cq = cb.createQuery(Entity.class);
Root<Entity> from = cq.from(Entity.class);
cq.select(Entity);
TypedQuery<Entity> q = em.createQuery(cq);
List<Entity> allitems = q.getResultList();

该查询演示了创建条件的基本步骤。

  • EntityManager实例用于创建CriteriaBuilder对象。

  • CriteriaQuery实例用于创建查询对象。 将使用查询的详细信息修改此查询对象的属性。

  • 调用CriteriaQuery.form方法来设置查询根。

  • 调用CriteriaQuery.select来设置结果列表类型。

  • TypedQuery《T》实例用于准备执行查询并指定查询结果的类型。

  • TypedQuery“T”对象上的getResultList方法来执行查询。 此查询返回实体集合,结果存储在List中。

标准API的示例

让我们考虑一下员工数据库的例子。 让我们假设jpadb.employee表包含以下记录:

Eid	 Ename          Salary	Deg
401	 Gopal	        40000	Technical Manager
402	 Manisha	    40000	Proof reader
403	 Masthanvali    35000	Technical Writer
404  Satish	        30000	Technical writer
405	 Krishna	    30000	Technical Writer
406	 Kiran	        35000	Proof reader

在名为JPA_Eclipselink_Criteria的eclipse IDE中创建JPA项目。 该项目的所有模块将在下面讨论:

创建实体 (Creating Entities)

'src'下创建一个名为com.iowiki.eclipselink.entity的包

在给定的包下创建一个名为Employee.java的类。 Employee实体类如下所示:

package com.iowiki.eclipselink.entity;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
@Entity
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 + "]";
	}
}

Persistence.xml

Persistence.xml文件如下:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" 
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
             xsi:schemaLocation="http://java.sun.com/xml/ns/persistence 
             http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
	<persistence-unit name="Eclipselink_JPA" 
                        transaction-type="RESOURCE_LOCAL">
	<class>com.iowiki.eclipselink.entity.Employee</class>
		<properties>
			<property name="javax.persistence.jdbc.url" 
			          value="jdbc:mysql://localhost:3306/jpadb"/>
			<property name="javax.persistence.jdbc.user" value="root"/>
			<property name="javax.persistence.jdbc.password" 
			          value="root"/>
			<property name="javax.persistence.jdbc.driver" 
			          value="com.mysql.jdbc.Driver"/>
			<property name="eclipselink.logging.level" value="FINE"/>
			<property name="eclipselink.ddl-generation" 
			          value="create-tables"/>
		</properties>
	</persistence-unit>
</persistence>

服务类

此模块包含服务类,它使用MetaData API初始化实现Criteria查询部分。 创建一个名为'com.iowiki.eclipselink.service'的包。 名为CriteriaAPI.java的类是在给定包下创建的。 DAO类如下所示:

package com.iowiki.eclipselink.service;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import com.iowiki.eclipselink.entity.Employee;
public class CriteriaApi 
{
	public static void main(String[] args) 
	{
		EntityManagerFactory emfactory = Persistence.
				createEntityManagerFactory( "Eclipselink_JPA" );
		EntityManager entitymanager = emfactory.
				createEntityManager( );
		CriteriaBuilder criteriaBuilder = entitymanager
				.getCriteriaBuilder();
		CriteriaQuery<Object> criteriaQuery = criteriaBuilder
				.createQuery();
		Root<Employee> from = criteriaQuery.from(Employee.class);
		//select all records
        System.out.println(“Select all records”);
		CriteriaQuery<Object> select =criteriaQuery.select(from);
		TypedQuery<Object> typedQuery = entitymanager
				.createQuery(select);
		List<Object> resultlist= typedQuery.getResultList();
		for(Object o:resultlist)
		{
			Employee e=(Employee)o;
			System.out.println("EID : "+e.getEid()
					+" Ename : "+e.getEname());
		}
		//Ordering the records 
        System.out.println(“Select all records by follow ordering”);
		CriteriaQuery<Object> select1 = criteriaQuery.select(from);
        select1.orderBy(criteriaBuilder.asc(from.get("ename")));
        TypedQuery<Object> typedQuery1 = entitymanager
        		.createQuery(select);
        List<Object> resultlist1= typedQuery1.getResultList();
		for(Object o:resultlist1)
		{
			Employee e=(Employee)o;
			System.out.println("EID : "+e.getEid()
					+" Ename : "+e.getEname());
		}
		entitymanager.close( );
		emfactory.close( );
	}
}

编译并执行上述程序后,您将在Eclipse IDE的控制台面板中获得以下输出。

Select All records
EID : 401 Ename : Gopal
EID : 402 Ename : Manisha
EID : 403 Ename : Masthanvali
EID : 404 Ename : Satish
EID : 405 Ename : Krishna
EID : 406 Ename : Kiran
Select All records by follow Ordering
EID : 401 Ename : Gopal
EID : 406 Ename : Kiran
EID : 405 Ename : Krishna
EID : 402 Ename : Manisha
EID : 403 Ename : Masthanvali
EID : 404 Ename : Satish
↑回到顶部↑
WIKI教程 @2018