`
mzhj
  • 浏览: 223788 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

07、使用JPA加载_更新_删除对象

阅读更多

 

PersonTest.java

package junit.test;

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

import org.junit.BeforeClass;
import org.junit.Test;

import cn.itcast.bean.Person;

public class PersonTest {

	@BeforeClass
	public static void setUpBeforeClass() throws Exception {
	}

	@Test public void save(){
		//对实体bean进行操作,第一步应该获取什么对象啊?     SessionFactory对象。
		//这里用获取的EntityManagerFactory对象,这可以把它看成跟Hibernate的SessionFactory对象差不多的东西。
		EntityManagerFactory factory = Persistence.createEntityManagerFactory("itcast");
		EntityManager em = factory.createEntityManager();
		em.getTransaction().begin();//开启事务
		em.persist(new Person("传智播客"));
		em.getTransaction().commit();
		em.close();
		factory.close();

		//SessionFactory  -->  Session  -->  begin事务
	}
	/*
session.save(obj);
    persist这方法在Hibernate里也存在,Hibernate的作者已经不太推荐大家用save方法,而是推荐大家用persist方法。
    why? 首先并不是代码上的问题,主要是这个名字上的问题,因为我们把这个ORM技术叫做持久化产品,那么我们对某个对象持久化,应该叫持久化,而不应该叫保存,所以后来Hibernate的作者推荐用persist方法,这并不是功能的问题,主要是取名的问题,所以用persist方法也可以。
	 */

	@Test public void getPerson(){
		EntityManagerFactory factory = Persistence.createEntityManagerFactory("itcast");
		EntityManager em = factory.createEntityManager();
		Person person = em.find(Person.class,1);	//相当于Hibernate的get方法,与load方法对应,不延迟加载。
		System.out.println(person.getName());
		em.close();
		factory.close();
	}

	@Test public void getPerson2(){
		EntityManagerFactory factory = Persistence.createEntityManagerFactory("itcast");
		EntityManager em = factory.createEntityManager();
		Person person = em.getReference(Person.class,1);
        //相当于Hibernate的load方法,延迟加载。
		//并不会立刻从数据库里面得到这条记录,只是返回了一个代理对象。
		System.out.println(person.getName());
        //这时候才会去数据库里得数据,发生加载行为。
		//这时候要确保实体管理器处于打开状态。
		em.close();
		//System.out.println(person.getName()); 如果屏蔽上上句,在这里才访问属性,那就会出错,延迟加载需要EntityManager没关闭,实际是hibernate的session没关闭。
		factory.close();
	}
   
    //jpa实体的四种状态:
	/*(1)new 新建状态。刚new出来的实体bean没有与任何EntityManager相关联就是新建状态。
	  (2)managed 托管状态(与EntityManager相关联,被EntityManager托管),用EntityManager的find和getReference方法查找出来的对象就是一个托管状态bean。
	  (3)游离状态。EntityManager对象调用clear方法,就把这个对象所托管的所有对象都变成游离状态的对象了。保存更改了处于游离状态的bean需要调用EntityManager对象的merge方法。
	  (4)删除状态。*/

	@Test public void updatePerson(){   //更改数据库里标志为1的那条记录的名字为老张,更改成功的两个条件:1、必须开启事务;2、这个bean对象处于托管状态。
		EntityManagerFactory factory = Persistence.createEntityManagerFactory("itcast");
		EntityManager em = factory.createEntityManager();
		em.getTransaction().begin(); //开启事务,只读取数据不需要开事务,更改数据的时候需要开事务。
		Person person=em.find(Person.class,1); //相当于Hibernate的get方法,第一个参数是实体Bean类(get方法采用泛型)(传什么类的class对象进去就返回什么类的对象回来),第二个参数是实体bean标识符的值(即ID的值,传入哪个id值返回的就是id为那个值的那条记录)。
		person.setName("老张");  //这个person是处于一个托管状态的bean对象,用set方法改变的属性并不会马上更新到数据库里面去,而是把这个操作放在一个jdbc的批处理里面,等到事务提交的时候才会更新到数据库里面去。
		em.getTransaction().commit();
		em.close();
		factory.close();
	}

	@Test public void updatePerson2(){
		EntityManagerFactory factory = Persistence.createEntityManagerFactory("itcast");
		EntityManager em = factory.createEntityManager();
		em.getTransaction().begin();	//开启事务。
		Person person=em.find(Person.class,1);
		em.clear();	//把实体管理器中的所有实体变成游离状态。
		person.setName("老黎");
		em.merge(person);    //更新处于游离状态的bean对象。
		em.getTransaction().commit();
		em.close();
		factory.close();
	}

	@Test public void delete(){
		EntityManagerFactory factory = Persistence.createEntityManagerFactory("itcast");
		EntityManager em = factory.createEntityManager();
		em.getTransaction().begin();	//开启事务。
		Person person=em.find(Person.class,1);
		em.remove(person);    //删除的bean对象也必须是处于托管状态的对象才能被删除成功。否则,如果person不是托管状态的bean,也不会报错但数据库内的数据也不会删除。
		em.getTransaction().commit();
		em.close();
		factory.close();
	}

}

 

 



     我们目前使用的是Hibernate,实际上我们操纵EntityManager对象时,它内部是操纵了Hibernate里面的sesson对象。它内部只是对session对象做了个封装而已。

 

   	@Test public void getPerson(){
		EntityManagerFactory factory = Persistence.createEntityManagerFactory("itcast");
		EntityManager em = factory.createEntityManager();
		Person person = em.find(Person.class,2);	//相当于Hibernate的get方法。
		System.out.println(person);
		em.close();
		factory.close();
	}

 

如果不存在id为2的person的话,那么返回的是null值 。

	@Test public void getPerson2(){
		EntityManagerFactory factory = Persistence.createEntityManagerFactory("itcast");
		EntityManager em = factory.createEntityManager();
		Person person = em.getReference(Person.class,2);     //1
		System.out.println(person);                          //2
		em.close();
		factory.close();
	}

 



    如果不存在id为2的person的话,那么返回的是异常(javax.persistence.EntityNotFoundException)。
    异常是在什么时候触发的呢? 是在1?还是2呢?
    答案是2。这说明并不是em.getReference()这个方法执行时就发生异常,而是在你访问这个对象或是它属性的时候才出现异常。

    数据库里没有相应的记录,EntityManagerd对象的get方法获取不到记录会返回null,而EntityManagerd对象的getReference方法获取不到记录会在下一次访问这个返回值的时候抛出异常。 

	@Test public void updatePerson2(){
		EntityManagerFactory factory = Persistence.createEntityManagerFactory("itcast");
		EntityManager em = factory.createEntityManager();
		em.getTransaction().begin();//开启事务。
		Person person=em.find(Person.class,1);
		em.clear();  //把实体管理器中的所有实体变成游离状态。
		person.setName("老黎");
		em.getTransaction().commit();
		em.close();
		factory.close();
	}

 

    在clear之后,person变成了游离状态,这时候对游离状态的实体进行更新的话(person.setName("老黎");),更新的数据是不能同步到数据库的。可以采用方法em.merge(person);这方法是用于把在游离状态时候的更新同步到数据库。 

分享到:
评论

相关推荐

    07_JPA详解_使用JPA加载_更新_删除对象.zip

    07_JPA详解_使用JPA加载_更新_删除对象.zip 07_JPA详解_使用JPA加载_更新_删除对象.zip

    07_传智播客JPA详解_使用JPA加载_更新_删除对象

    07_传智播客JPA详解_使用JPA加载_更新_删除对象.rar

    JPA加载_更新_删除对象及使用JPQL语句进行查询

    JPA加载_更新_删除对象及使用JPQL语句进行查询

    经典JAVA.EE企业应用实战.基于WEBLOGIC_JBOSS的JSF_EJB3_JPA整合开发.pdf

    第二部分详细讲解了jsf ri、jta、jndi、rmi、jms、javamail、ejb 3的session bean、message driven bean、jpa、jax-ws 2、jaas等java ee知识,这部分知识以jsf+ejb 3+jpa整合开发为重点,通过使用netbeans ide工具...

    jpa-hibernate-alura:Alura的Java和JPA课程

    Alura-Java和JPA课程:使用JPA2和Hibernate持久化对象 这是我在课程之后开发的代码。 我已经对原始版本进行了一些更改。 内容 JPA和Hibernate简介 使用数据库 面向对象范式 在Java代码中避免使用SQL JDBC和SQL维护...

    Book_Administration_App:描述

    用户可以对3个对象执行各种操作(添加,删除,更改):书籍,作者和出版者。使用一个简单的Web界面,该界面是使用百里香叶和CRUD后端制作的。该应用程序使用Spring Security进行保护。 附带预加载的数据: 用户: ...

    Java EE常用框架.xmind

    当用户需要查询的时候,就使用IndexSearcher从索引库中读取数据,找到对应的Document对象,从而解析里边的内容 最后将内容封装到JavaBean对象中 索引库优化 合并文件 采用一种算法,将中英文本...

    springboot知识点整理

    7.1.1 创建SpringApplication对象 129 7.1.2 运行run方法 130 7.1.3 编写事件监听机制 132 8 Spring Boot自定义starters 136 8.1 概述 136 8.2 步骤 137 9 更多Springboot整合示例 144 10 Spring Boot与缓存 145 ...

    Hibernate注解

    很奇怪),分别是CascadeType.PERSIST(级联新建),CascadeType.REMOVE(级联删除),CascadeType.REFRESH(级联刷新),CascadeType.MERGE(级联更新),CascadeType.ALL(全部四项) * 方法一 * 主表: ?@OneToOne...

    Spring攻略(第二版 中文高清版).part2

    10.5 使用服务器端对象 418 10.5.1 问题 418 10.5.2 解决方案 418 10.5.3 工作原理 418 10.6 使用BlazeDS和Spring消费面向消息的服务 421 10.6.1 问题 421 10.6.2 解决方案 422 10.6.3 工作原理 422...

    Spring攻略(第二版 中文高清版).part1

    10.5 使用服务器端对象 418 10.5.1 问题 418 10.5.2 解决方案 418 10.5.3 工作原理 418 10.6 使用BlazeDS和Spring消费面向消息的服务 421 10.6.1 问题 421 10.6.2 解决方案 422 10.6.3 工作原理 422...

    Java常见面试题208道.docx

    面试题包括以下十九部分:Java 基础、容器、多线程、反射、对象拷贝、Java Web 模块、异常、网络、设计模式、Spring/Spring MVC、Spring Boot/Spring Cloud、Hibernate、Mybatis、RabbitMQ、Kafka、Zookeeper、MySql...

Global site tag (gtag.js) - Google Analytics