一、JPA 入门

Java Persistence API:用于对象持久化的 API
Java EE 5.0 平台标准的 ORM 规范,使得应用程序以统一的方式访问持久层

1. JPA 概述

架构图:

绘图1.png

JPA和Hibernate的关系:

JPA 是 hibernate 的一个抽象(就像JDBC和JDBC驱动的关系):

  • JPA 是规范:JPA 本质上就是一种 ORM 规范,不是ORM 框架 —— 因为 JPA 并未提供 ORM 实现,它只是制订了一些规范,提供了一些编程的 API 接口,但具体实现则由 ORM 厂商提供实现

  • Hibernate 是实现:Hibernate 除了作为 ORM 框架之外,它也是一种 JPA 实现

  • 从功能上来说, JPA 是 Hibernate 功能的一个子集

JPA 的实现(JPA 供应商):

  • Hibernate:
    JPA 的开发者就是 Hibernate 和 EJB 的开发者
    Hibernate 从 3.2 开始兼容 JPA

  • OpenJPA
    OpenJPA 是 Apache 组织提供的开源项目

  • TopLink
    TopLink 以前需要收费,如今开源了,Oracle 公司的项目

JPA 的优势:

  • 标准化: 提供相同的 API,这保证了基于JPA 开发的企业应用能够经过少量的修改就能够在不同的 JPA 框架下运行。

  • 简单易用,集成方便: JPA 的主要目标之一就是提供更加简单的编程模型,在 JPA 框架下创建实体和创建 Java 类一样简单,只需要使用 javax.persistence.Entity 进行注释;JPA 的框架和接口也都非常简单。

  • 可媲美JDBC的查询能力: JPA的查询语言是面向对象的,JPA定义了独特的JPQL,而且能够支持批量更新和修改、JOIN、GROUP BY、HAVING 等通常只有 SQL 才能够提供的高级查询特性,甚至还能够支持子查询。

  • 支持面向对象的高级特性: JPA 中能够支持面向对象的高级特性,如类之间的继承、多态和类之间的复杂关系,最大限度的使用面向对象的模型

JPA 主要 3 技术(掌握)

  • ORM 映射元数据:JPA 支持 XML 和 JDK 5.0 注解两种元数据的形式,元数据描述对象和表之间的映射关系,框架据此将实体对象持久化到数据库表中。

  • JPA 的 API:用来操作实体对象,执行CRUD操作,框架在后台完成所有的事情,开发者从繁琐的 JDBC和 SQL代码中解脱出来。

  • 查询语言(JPQL):这是持久化操作中很重要的一个方面,通过面向对象而非面向数据库的查询语言查询数据,避免程序和具体的 SQL 紧密耦合

2. JPA 持久化对象开发步骤:

2.1 导入 HIBERNATE JPA 实现(配置 POM 文件)

    <dependencies>
        <!--配置 HIBERNATE JPA 实现包 -->
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-entitymanager</artifactId>
            <version>5.2.12.Final</version>
        </dependency>
    </dependencies>

2.2 创建 persistence.xml, 在这个文件中配置持久化单元

注意:persistence.xml 放置于 类路径下的 META-INF 目录下,persistence.xml 文件名称固定

图片.png

  • 需要配置连接数据库信息
  • 需要指定 JPA 使用哪个持久化的框架以及配置该框架的基本属性
  • 需要指定持久化的实体类
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence" version="2.1">
    <!--persistence-unit 定义持久化单元:
        name 属性:定义持久化单元名称
        transaction-type 属性:定义事务类型,此处为本地事务 RESOURCE_LOCAL-->
    <persistence-unit name="helloJpa" transaction-type="RESOURCE_LOCAL">
       <!-- provider 配置 实现 JPA 的 ORM 持久化框架-->
        <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
       <!-- properties 定义连接数据库信息-->
        <properties>
            <!-- jpa中连接数据库 -->
            <property name="javax.persistence.jdbc.driver" value="oracle.jdbc.OracleDriver" />
            <property name="javax.persistence.jdbc.url" value="jdbc:oracle:thin:@192.168.0.112:1521:XE" />
            <property name="javax.persistence.jdbc.user" value="ZHANGJIAN" />
            <property name="javax.persistence.jdbc.password" value="zhangjian"></property>

            <!-- jpa中配置hibernate基本属性 -->
            <property name="hibernate.show_sql" value="true" />
            <property name="hibernate.format_sql" value="true" />
          <!--  <property name="hibernate.hbm2ddl.auto" value="update" />-->
            <property name="hibernate.dialect" value="org.hibernate.dialect.Oracle10gDialect" />
        </properties>
    </persistence-unit>
</persistence>

2.3 创建持久化实体类

package org.zj.jpa.demo.entity;

import javax.persistence.*;
import java.math.BigDecimal;
import java.util.Date;

/**
 * Created by ZhangJian on 2018/1/17.
 */
@Entity
@Table(name = "t_order")
public class OrderEntity {
    @Id
    @SequenceGenerator(name="seq_name",sequenceName = "order_seq",allocationSize = 1)
    @GeneratedValue(generator = "seq_name")
    private Long id;
    private String description;
    private BigDecimal totalMoney;

    @Temporal(TemporalType.TIMESTAMP)
    private Date createOrderTime;
    private Integer state;

2.4 测试

package org.zj.jpa.demo.test;

import org.zj.jpa.demo.entity.OrderEntity;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import java.math.BigDecimal;
import java.sql.Timestamp;
import java.util.Date;

/**
 * Created by ZhangJian on 2018/1/17.
 */
public class App {
    public static void main(String[] args) {

        // 创建 EntityManagerFactory 对象 类似于 Hibernate 中 sessionFactory 对象
        EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("helloJpa");
        // 创建 EntityManager 对象 类似于 Hibernate 中的 Session 对象
        EntityManager entityManager = entityManagerFactory.createEntityManager();
        // 开启事务
        entityManager.getTransaction().begin();

        // 持久化实体操作
        OrderEntity order =  new OrderEntity();
        order.setCreateOrderTime(new Timestamp(new Date().getTime()));
        order.setDescription("田鸡又肚子疼");
        order.setState(1);
        order.setTotalMoney(new BigDecimal(2000));

        entityManager.persist(order);


        // 提交事务
        entityManager.getTransaction().commit();
        entityManager.close();
        entityManagerFactory.close();

    }
}

3.注解元数据介绍

/**
 * Entity 注解: 定义该类为持久化类
 *      name 属性:定义数据库中的表名 跟 该持久化类进行关联,可以不配,默认关联的以实体类的类名对应的表。
 * Table 注解: 如果数据库中没有表,使用该注解,定义自动创建表的时候的表名
 *
 * ID 注解 : 定义标识属性
 * GeneratedValue 注解: 描述主键的生成的策略
 *          JPA  使用 GenerationType 该枚举类型定义了 4 种 生成策略:
 *              AUTO: 底层是否支持自增长或者序列
 *              IDENTITY:必须 数据库支持 自增长策略。 mysql
 *              SEQUENCE:支持序列的数据库,oracle :HIBERNATE_SEQ
 *              TABLE: hibernate 自动创建一个 Table 来保存主键值。
 *
 * SequenceGenerator 注解:定义创建序列的规则
 *
 *
 * Column 注解: 定义对应的表的字段的名称,约束的规则(定义长度,唯一....),该注解可以不配,不配默认使用实体属性名称作为表的列名称
 *
 *
 * Temporal 注解:定义表中日期的列采用具体的日期类型。
 *      JPA 使用 TemporalType 该枚举类型 定义了 3z 中 数据库日期类型:
 *          date:带年月日
 *          time:带时分秒
 *          TIMESTAMP:带年月日时分秒后面的更加精确的时间
 *
 * Transient 注解:指定修饰的属性,不作为表中的列。忽略该属性
 */
@Entity
@Table(name = "t_order")
public class OrderModel {

    @Id
    @GeneratedValue(generator = "order_seq")
    @SequenceGenerator(name = "order_seq",sequenceName = "order_seq",allocationSize = 1)
    private Long id;

    private String description;

    @Temporal(TemporalType.TIMESTAMP)
    private Date createOrdTime;
    private Integer state;
    private Double totalMoney;

    @Transient
    private  String noCreateColumn;

4. JPA 常用 API

  • Persistence:JPA 提供的一个获取 EntityManagerFactory 对象的工具类
    Persistence.createEntityManagerFactory("helloJpa")

  • EntityManagerFactory JPA 应用中只有一份,通过它创建 EntityManager 对象。

  • EntityManager 封装 CRUD 基本操作,管理 实体对象状态,一级缓存。
    entityManager.persist(order):没有主键的返回值,该方法的执行也会把一个临时状态的 对象转为受容器管理的 持久化对象。只有在刷新容器或者事务提交的时候,才会发 insert 语句到 数据库。
    entityManager.find(OrderModel.class, 1L):返回的是受容器管理的真实的类型的对象,立即加载。
    entityManager.getReference(OrderModel.class,1l):返回的是受容器管理的真实的类型的对象,懒加载
    更新操作方式1,使用快照更新:OrderModel orderModel = entityManager.find(OrderModel.class, 1L);
    orderModel.setDescription("通过快照更新,没有显示的调用 meger方法");
    更新操作方式2,meger: 传入参数对象如果是 DO 对象,执行完该方法然后是 DO 对象,但是方法执行后返回的是 PO 对象。merger 更新的 DO 对象会把更新的数据就会覆盖容器中已经存在的要修改的 PO 对象数据。merger 的参数对象是 TO ,就会执行 insert 操作。
    entityManager.remove(orderModel):删除的参数对象为 PO 对象
    entityManager.createQuery("from OrderModel "):创建 Quqery 接口,需要出入 JPQL 语句。

  • Quqery 接口 API:
    query.getResultList():查询记录使用 List 封装。
    query.getSingleResult(): 查询当行记录
    setFirstResult(0): 设置开始下标
    setMaxResults(1):设置抓取记录条数
    jpql 带参数的查询支持三种:请看hibernate*

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 196,200评论 5 462
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 82,526评论 2 373
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 143,321评论 0 325
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,601评论 1 267
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,446评论 5 358
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,345评论 1 273
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,753评论 3 387
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,405评论 0 255
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,712评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,743评论 2 314
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,529评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,369评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,770评论 3 300
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,026评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,301评论 1 251
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,732评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,927评论 2 336

推荐阅读更多精彩内容