JPA-3 核心API

  JPA的核心API主要包括Persistence、EntityManagerFactory、EntityManager和EntityTransaction等。
  其中,JPA核心API的具体测试代码下载地址:。


1. Persistence

  主要作用:通过createEntityManagerFactory()静态方法来获取EntityManagerFactory的实例。

// 1. 创建EntityManagerFactory
String persistenceUnitName = "JPA-3-EntityManager";
EntityManagerFactory entityManagerFactory = null;

entityManagerFactory = Persistence.createEntityManagerFactory(persistenceUnitName);

/* 了解
Map<String, Object> properties = new HashMap<>();
properties.put("hibernate.show_sql", false);
entityManagerFactory = Persistence.createEntityManagerFactory(persistenceUnitName, properties);
 */

2. EntityManagerFactory

  主要作用:该接口主要用来创建EntityManager的实例。

主要方法具体描述
createEntityManager()用于创建实体管理器对象实例
createEntityManager(Map map)用于创建实体管理器对象实例的重载方法,Map参数用于提供EntityManager的属性
isOpen()检查EntityManagerFactory是否处于打开状态;实体管理器工厂实例创建后一直处于打开状态,除非调用close()方法将其关闭
close()关闭EntityManagerFactory;关闭后将释放所有资源,isOpen()方法测试将返回false,其它方法将不能调用,否则将导致IllegalStateException异常
// 2. 创建EntityManager
EntityManager entityManager = entityManagerFactory.createEntityManager();

3. EntityManager

  主要作用:JPA规范中完成持久化操作的核心对象,在一组实体类与底层数据源之间进行O/R映射的管理。
  在JPA规范中,实体具有如下四种状态:

实体状态具体描述
新建状态新创建的对象,尚未拥有持久性主键
持久化状态已经拥有持久性主键并和持久化建立了上下文环境
游离状态拥有持久化主键,但是没有与持久化建立上下文环境
删除状态拥有持久化主键,已经和持久化建立上下文环境,但是从数据库中删除
3.1 find()/getReference()/persist()/remove()

  这里写图片描述
  

package com.qiaobc.jpa.junit;

import java.util.Date;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Persistence;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import com.qiaobc.jpa.em.Customer;

public class JPATest {

    private EntityManagerFactory entityManagerFactory;
    private EntityManager entityManager;
    private EntityTransaction entityTransaction;

    @Before
    public void init() {
        String persistenceUnitName = "JPA-3-EntityManager";
        entityManagerFactory = Persistence.createEntityManagerFactory(persistenceUnitName);
        entityManager = entityManagerFactory.createEntityManager();
        entityTransaction = entityManager.getTransaction();

        // 开启事务
        entityTransaction.begin();
    }

    /**
     * find()方法 : 类似于Hibernate中Session的get()方法
     */
    @Test
    public void testFind() {
        Customer customer = entityManager.find(Customer.class, 1);
        System.out.println(customer.getClass().getName()); // com.qiaobc.jpa.em.Customer
        System.out.println("******");
        System.out.println(customer);
    }

    /**
     * getReference()方法 : 类似于Hibernate中Session的load()方法
     */
    @Test
    public void testGetReference() {
        Customer customer = entityManager.getReference(Customer.class, 1);
        System.out.println(customer.getClass().getName()); // com.qiaobc.jpa.em.Customer_$$_javassist_0

//      org.hibernate.LazyInitializationException: could not initialize proxy - no Session
//      entityTransaction.commit();
//      entityManager.close();

        System.out.println("******");
        System.out.println(customer);
    }

    /**
     * persist()方法 : 类似于Hibernate中Session的save()方法
     * 
     * 不同之处:若对象有id则persist()方法不能执行INSERT操作,而会抛出异常
     */
    @Test
    public void testPersist() {
        Customer customer = new Customer(null, "qiaob", "qiaob@163.com", 22, new Date(), new Date());
        entityManager.persist(customer); // 使对象由临时状态变为持久化状态
        System.out.println("id = " + customer.getId());
    }

    /**
     * remove()方法 : 类似于Hibernate中Session的delete()方法
     * 
     * 不同之处:只能移除持久化对象,但delete()方法实际上还可移除游离对象
     */
    @Test
    public void testRemove() {
        Customer customer = new Customer();
        customer.setId(1);
//      entityManager.remove(customer); // 不能移除游离对象

        customer = entityManager.find(Customer.class, 1);
        entityManager.remove(customer);
    }

    @After
    public void destory() {
        entityTransaction.commit();
        entityManager.close();
        entityManagerFactory.close();
    }

}
3.2 merge()

  主要作用:用于处理Entity的同步,即数据库的插入和更新操作,类似于Hibernate中Session的saveOrUpdate()方法。
  运行流程:若news1为临时对象,则创建新的news2对象,将news1对象的属性复制到news2对象中,并持久化news2对象,进而返回持久化对象news2的引用。若news1为游离对象(设OID=1),则先在EntityManager缓存中查找是否存在OID为1的持久化对象news3,若存在则将news1对象的属性复制到news3对象中,并持久化news3对象,进而返回持久化对象的引用;若不存在则在数据库中查找是否存在ID为1的记录,若存在则加载该记录对应的持久化对象news4,将news1对象的属性复制到news4对象中,并持久化news4对象,进而返回持久化对象的引用。
  这里写图片描述

/**
 * 临时对象的持久化过程:
 *  1). 创建新的对象
 *  2). 将临时对象的属性赋值到新创建的对象属性中
 *  3). 持久化新创建的对象
 *  4). 返回新创建的对象的引用
 */
@Test
public void testMerge1() {
    // 临时对象
    Customer customer1 = new Customer(null, "qiaobc", "qiaobc@163.com", 23, new Date(), new Date());

    // 持久化该临时对象
    Customer customer2 = entityManager.merge(customer1);

    System.out.println(customer1 == customer2); // false
    System.out.println("customer1#id: " + customer1.getId());   // null
    System.out.println("customer2#id: " + customer2.getId());   // 不为null
}

/**
 * 游离对象的持久化过程:
 *  1). 若EntityManager缓存中存在与游离对象OID相同的持久化对象
 *  2). 将游离对象的属性复制到持久化对象的属性中
 *  3). 持久化复制后的持久化对象
 *  4). 返回该持久化对象的引用
 * 
 * 特别注意:Hibernate不允许Session在同一时刻与两个OID相同的对象进行关联,而EntityManager可以
 */
@Test
public void testMerge2() {
    // 游离对象
    Customer customer1 = new Customer(1, "qiaodb", "qiaodb@163.com", 22, new Date(), new Date());

    // 缓存中加载OID=1的持久化对象
    Customer customer2 = entityManager.find(Customer.class, 1);

    // 持久化该游离对象
    entityManager.merge(customer1);

    System.out.println(customer1 == customer2); // false
    System.out.println("customer1#id: " + customer1.getId());   // 1
    System.out.println("customer2#id: " + customer2.getId());   // 1
}

/**
 * 游离对象的持久化过程:
 *  1). 若EntityManager缓存中不存在与游离对象OID相同的持久化对象
 *  2). 若数据库中存在id=OID的记录,则从该数据库中加载id=OID的持久化对象
 *  3). 将游离对象的属性复制到持久化对象的属性中
 *  4). 持久化复制后的持久化对象
 *  5). 返回该持久化对象的引用
 */
@Test
public void testMerge3() {
    // 游离对象
    Customer customer1 = new Customer(1, "qiaobb", "qiaobb@163.com", 22, new Date(), new Date());

    // 持久化该游离对象
    Customer customer2 = entityManager.merge(customer1);

    // 通过setName()方法设置断点来查看效果
    System.out.println(customer1 == customer2); // false
}
3.3 其他方法

  这里写图片描述

@Test
public void testFlush() {
    Customer customer = entityManager.find(Customer.class, 1);
    System.out.println(customer);

    customer.setName("qiaobendan");
    entityManager.flush(); // 强制将修改后的实体保存到数据库中,否则只在事务提交时保存
}

@Test
public void testRefresh() {
    Customer customer = entityManager.find(Customer.class, 1);
    customer = entityManager.find(Customer.class, 1);

    entityManager.refresh(customer); // 强制重新获取customer实体
}

4. EntityTransaction

  主要作用:用来管理资源层实体管理器的事务操作,可通过调用实体管理器的getTransaction()方法来获得其实例。
  这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值