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