JPA - ORM 组件



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

对象关系映射

对象关系映射 (ORM) 简要介绍了什么是 ORM 及其工作原理。ORM 是一种将数据从对象类型转换为关系类型,反之亦然的能力。

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

高级功能

  • 惯用的持久化:它使您能够使用面向对象的类编写持久化类。

  • 高性能:它具有多种获取技术和乐观锁定技术。

  • 可靠性:它高度稳定且卓越。被许多工业程序员使用。

ORM 架构

以下是 ORM 架构。

Object Relational Mapping

上图说明了对象数据如何分三个阶段存储到关系数据库中。

阶段1

第一阶段,称为对象数据阶段,包含 POJO 类、服务接口和类。它是主要的业务组件层,包含业务逻辑操作和属性。

例如,让我们以员工数据库作为模式 -

  • Employee POJO 类包含诸如 ID、姓名、工资和职位之类的属性。以及这些属性的 setter 和 getter 方法。

  • Employee DAO/Service 类包含服务方法,例如创建员工、查找员工和删除员工。

阶段 2

第二阶段称为映射持久化阶段,其中包含 JPA 提供程序、映射文件 (ORM.xml)、JPA 加载程序和对象网格。

  • JPA 提供程序:包含 JPA 风格 (javax.persistence) 的供应商产品。例如 Eclipselink、Toplink、Hibernate 等。

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

  • JPA 加载程序:JPA 加载程序的工作原理类似于缓存内存,可以加载关系网格数据。它就像数据库的副本,与服务类交互以获取 POJO 数据(POJO 类的属性)。

  • 对象网格:对象网格是一个临时位置,可以存储关系数据的副本,即类似于缓存内存。所有针对数据库的查询首先都会在对象网格中的数据上生效。只有在提交后,它才会影响主数据库。

阶段 3

第三阶段是关系数据阶段。它包含与业务组件逻辑连接的关系数据。如上所述,只有当业务组件提交数据时,它才会物理存储到数据库中。在此之前,修改后的数据会以网格格式存储在缓存内存中。获取数据的过程也是如此。

上述三个阶段的程序化交互机制称为对象关系映射。

Mapping.xml

mapping.xml 文件用于指示 JPA 供应商将实体类与数据库表进行映射。

让我们以包含四个属性的 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 类。它包含四个属性 eid、ename、salary 和 deg。假设这些属性是数据库中的表字段,并且 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>:标记定义架构定义,以允许将实体标记放入 xml 文件中。

  • <description>:标记定义有关应用程序的描述。

  • <entity>:标记定义要转换为数据库中表的实体类。class 属性定义 POJO 实体类名称。

  • <table>:标记定义表名。如果要将类名作为表名,则此标记不是必需的。

  • <attributes>:标记定义属性(表中的字段)。

  • <id>:标记定义表的主键。<generated-value> 标记定义如何分配主键值,例如自动、手动或从序列中获取。

  • <basic>:标记用于定义表的其余属性。

  • <column-name>:标记用于定义用户定义的表字段名称。

注解

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

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

以下是我们示例中使用的注解列表

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

Java Bean 标准

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

Bean 约定

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

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

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

  • 布尔属性包含setteris 方法。

  • 任何属性的getter 方法都应以小写字母“get”(java 方法约定)开头,然后是首字母大写的字段名称。例如,字段名称为“salary”,因此该字段的 getter 方法为“getSalary()”。

  • 任何属性的setter 方法都应以小写字母“set”(java 方法约定)开头,然后是首字母大写的字段名称,以及要设置为字段的参数值。例如,字段名称为“salary”,因此该字段的 setter 方法为“setSalary(double sal)”。

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

广告