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);这方法是用于把在游离状态时候的更新同步到数据库。