Persistance获取EntityManagerFactory的方法

1.通过传入persistenceUnitName来获取

EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory(persistenceUnitName);

2.

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


在 JPA 规范中, EntityManager是完成持久化操作的核心对象。实体作为普通 Java 对象,只有在调用 EntityManager将其持久化后才会变成持久化对象。EntityManager对象在一组实体类与底层数据源之间进行 O/R 映射的管理。它可以用来管理和更新 Entity Bean, 根椐主键查找 Entity Bean, 还可以通过JPQL语句查询实体。

实体的状态:

新建状态:   新创建的对象,尚未拥有持久性主键

持久化状态:已经拥有持久性主键并和持久化建立了上下文环境

游离状态拥有持久化主键,但是没有与持久化建立上下文环

删除状态:  拥有持久化主键,已经和持久化建立上下文环境,但是从数据库中删除

public class JPATest {

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

	@Before
	public void init() {
		entityManagerFactory = Persistence.createEntityManagerFactory("Jpa");
		entityManager = entityManagerFactory.createEntityManager();
		entityTransaction = entityManager.getTransaction();
		entityTransaction.begin();
	}

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

	// 类似Hibernate中session的get方法
	@Test
	public void testFind() {
		// 执行find方法的时候就发送sql语句查询数据库
		Customer customer = entityManager.find(Customer.class, 1);
		System.out.println("-------------------");
		System.out.println(customer);
	}

	// 类似Hibernate中session的load方法
	@Test
	public void testGetRefrence() {
		Customer customer = entityManager.getReference(Customer.class, 1);
		System.out.println("-------------------");
		// 真正使用对象的时候才会发送sql语句查询数据库
		System.out.println(customer);
	}

	// 类似Hibernate中session的save方法,和save方法不同,若对象有id则不同执行insert操作而抛出异常
	@Test
	public void testPersistence() {
		Customer customer = new Customer();
		customer.setAge(30);
		customer.setEmail("umgsai@163.com");
		customer.setLastName("SS");
		entityManager.persist(customer);
		System.out.println(customer.getId());// 对象由临时状态变为持久化状态
	}

	// 类似Hibernate中session的delete方法,只能移除持久化对象。Hibernate的delete方法还可以移除游离对象
	@Test
	public void testDelete() {
		/*
		 * 不能移除游离对象
		 *  Customer customer = new Customer(); 
		 *  customer.setId(2);
		 * entityManager.remove(customer);
		 */
		Customer customer = entityManager.find(Customer.class, 2);
		entityManager.remove(customer);
	}
	
		//类似Hibernate Session的saveOrUpdate方法
	@Test
	public void testMerge1() {
		//临时对象,没有id
		Customer customer = new Customer();
		customer.setAge(24);
		customer.setEmail("ss@126.com");
		customer.setLastName("DD");
		//会创建一个新的对象,把临时对象的属性复制到新的对象,然后对新的对象执行持久化操作
		//新的对象有id,但之前的临时对象中没有id
		Customer customer2 = entityManager.merge(customer);
		System.out.println(customer);//Customer [id=null, lastName=DD, email=ss@126.com, age=24]
		System.out.println(customer2);//Customer [id=5, lastName=DD, email=ss@126.com, age=24]
	}
	
		@Test
		public void testMerge2() {
			//游离对象,有id属性
			//若在EntityManager缓存中没有该对象
			//若在数据库中也没有对应的记录
			//JPA会创建一个新的对象,把当前游离对象的属性复制到新创建的对象中
			//对新创建的对象执行insert操作
			Customer customer = new Customer();
			customer.setAge(24);
			customer.setEmail("ss@126.com");
			customer.setLastName("DD");
			customer.setId(35);
			Customer customer2 = entityManager.merge(customer);
			System.out.println(customer);//Customer [id=35, lastName=DD, email=ss@126.com, age=24]//数据库中并没有此记录
			System.out.println(customer2);//Customer [id=6, lastName=DD, email=ss@126.com, age=24]
		}
		
		@Test
		public void testMerge3() {
			//游离对象,有id属性
			//若在EntityManager缓存中没有该对象
			//若在数据库中有对应的记录
			//JPA会查询对应的记录,返回该记录对应的对象,然后把游离对象的属性复制到查询出的对象中
			//对查询到的对象执行update
			Customer customer = new Customer();
			customer.setAge(23);
			customer.setEmail("ss@126.com");
			customer.setLastName("DD");
			customer.setId(7);
			Customer customer2 = entityManager.merge(customer);
			System.out.println(customer);//Customer [id=6, lastName=DD, email=ss@126.com, age=23]
			System.out.println(customer2);//Customer [id=6, lastName=DD, email=ss@126.com, age=23]
		}
		
		@Test
		public void testMerge4() {
			//游离对象,有id属性
			//若在EntityManager缓存有该对象
			//JPA会把游离对象的属性复制到缓存中的对象中
			//然后对缓存中的对象执行update
			Customer customer = new Customer();
			customer.setAge(23);
			customer.setEmail("ss@126.com");
			customer.setLastName("DD");
			customer.setId(7);
			
			Customer customer2 = entityManager.find(Customer.class, 7);//缓存中存在id为7的对象
			entityManager.merge(customer);
			
			System.out.println(customer == customer2);//false
		}
		
		//与Hibernate中session的flush方法
		@Test
		public void testFlush() {
			Customer customer = entityManager.find(Customer.class, 6);
			System.out.println(customer);
			customer.setLastName("shang");
			
			entityManager.flush();//刷新数据库,强制发送update
		}

}


EntityManager的其他方法

flush ()同步持久上下文环境,即将持久上下文环境的所有未保存实体的状态信息保存到数据库中。setFlushMode (FlushModeTypeflushMode):设置持久上下文环境的Flush模式。参数可以取2个枚举–FlushModeType.AUTO为自动更新数据库实体,–FlushModeType.COMMIT为直到提交事务时才更新数据库记录。getFlushMode():获取持久上下文环境的Flush模式。返回FlushModeType类的枚举值。

refresh(Objectentity):用数据库实体记录的值更新实体对象的状态,即更新实例的属性值。clear():清除持久上下文环境,断开所有关联的实体。如果这时还有未提交的更新则会被撤消。contains (Objectentity):判断一个实例是否属于当前持久上下文环境管理的实体。

isOpen ():判断当前的实体管理器是否是打开状态。

getTransaction ():返回资源层的事务对象。EntityTransaction实例可以用于开始和提交多个事务。close ():关闭实体管理器。之后若调用实体管理器实例的方法或其派生的查询对象的方法都将抛出 IllegalstateException异常,除了getTransaction和 isOpen方法(返回 false)。不过,当与实体管理器关联的事务处于活动状态时,调用 close 方法后持久上下文将仍处于被管理状态,直到事务完成。


EntityTransaction

EntityTransaction接口用来管理资源层实体管理器的事务操作。通过调用实体管理器的getTransaction方法 获得其实例。

begin ()–用于启动一个事务,此后的多个数据库操作将作为整体被提交或撤消。若这时事务已启动则会抛出 IllegalStateException异常。

commit ()–用于提交当前事务。即将事务启动以后的所有数据库更新操作持久化至数据库中。

rollback ()撤消(回滚)当前事务。即撤消事务启动后的所有数据库更新操作,从而不对数据库产生影响。

setRollbackOnly ()–使当前事务只能被撤消。

getRollbackOnly ()–查看当前事务是否设置了只能撤消标志。

isActive ()–查看当前事务是否是活动的。如果返回true则不能调用begin方法,否则将抛出 IllegalStateException异常;如果返回 false 则不能调用 commit、rollback、setRollbackOnly及 getRollbackOnly方法,否则将抛出 IllegalStateException异常。