标签:inter 实体类 北京 保存数据 llb 完成 com persist int
Persistence / EntityManagerFactory / EntityManager / EntityTransaction
Hibernate JPA
的操作步骤:
1. 加载配置文件创建实体管理器工厂
2. 根据实体管理器工厂,创建实体管理器
3. 创建事务对象,开启事务
4. 完成增删改查操作
5. 提交事务(回滚事务)
6. 释放资源
Persistence对象(创建实体管理器工厂)
/**
* Persisitence.createEntityMnagerFactory(持久化单元名称)
* 静态方法(根据持久化单元名称创建实体管理器工厂)
**/
// 1.加载配置文件创建工厂(实体管理器工厂)对象
EntityManagerFactory factory = Persistence.createEntityManagerFactory("myJpa");
Persistence
对象主要作用是用于获取EntityManagerFactory
对象的 。通过调用该类的createEntityManagerFactory
静态方法,根据配置文件中持久化单元名称创建EntityManagerFactory
。
EntityManagerFactory(
EntityManagerFactory
接口主要用来创建EntityManager
实例)
/**
* entityManagerFactory.createEntityManager():获取EntityManager对象
* 内部维护的很多的内容:
* 1.内部维护了数据库信息
* 2.维护了缓存信息
* 3.维护了所有的实体管理器对象
* 4.在创建EntityManagerFactory的过程中会根据配置创建数据库表
* EntityManagerFactory的创建过程比较浪费资源
* 特点:线程安全的对象,多个线程访问同一个EntityManagerFactory不会有线程安全问题
* 如何解决EntityManagerFactory的创建过程浪费资源(耗时)的问题?
* 思路:创建一个公共的EntityManagerFactory的对象
* 静态代码块的形式创建EntityManagerFactory
**/
// 2.通过实体管理器工厂获取实体管理器
EntityManager em = factory.createEntityManager();
EntityManager
/**
* EntityManager:实体类管理器
* 获取事务对象: getTransaction()
* 保存数据: presist()
* 更新数据: merge()
* 删除数据: remove()
* 根据id查询: find()/getRefrence():
* ......(还有挺多方法可以自己慢慢琢磨)
**/
// 3.获取事务对象,然后可以开启事务、提交事务、回滚事务
EntityTransaction tx = em.getTransaction();
在 JPA 规范中, EntityManager
是完成持久化操作的核心对象。实体类作为普通 java对象,只有在调用 EntityManager
将其持久化后才会变成持久化对象。EntityManager
对象在一组实体类与底层数据源之间进行 O/R 映射的管理。它可以用来管理和更新 Entity Bean, 根椐主键查找 Entity Bean
, 还可以通过JPQL语句查询实体。我们可以通过调用EntityManager
的方法完成获取事务,以及持久化数据库的操作
EntityTransaction
/**
* EntityTransaction: 事务对象
* 开启事务: begin()
* 提交事务: commit()
* 回滚事务: rollback()
**/
// 开启事务
tx.begin();
在 JPA 规范中, EntityTransaction
是完成事务操作的核心对象,对于EntityTransaction
在我们的 java 代码中承接的功能比较简单
保存操作
/**
* 运行之前,修改hibernate.hbm2ddl.auto=create
* 保存操作
*/
@Test
public void testSave() {
// 获取实体管理器工厂
EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("myJpa");
// 获取实体管理器
EntityManager entityManager = entityManagerFactory.createEntityManager();
// 获取事务
EntityTransaction transaction = entityManager.getTransaction();
// 开启事务
transaction.begin();
// 创建实体对象并保存
Customer customer1 = new Customer();
customer1.setName("张三");
customer1.setAge(20);
customer1.setSex(true);
customer1.setPhone("13018882888");
customer1.setAddress("北京");
entityManager.persist(customer1);
Customer customer2 = new Customer();
customer2.setName("李四");
customer2.setAge(18);
customer2.setSex(false);
customer2.setPhone("13533333555");
customer2.setAddress("广州");
entityManager.persist(customer2);
Customer customer3 = new Customer();
customer3.setName("王五");
customer3.setAge(28);
customer3.setSex(true);
customer3.setPhone("13012345678");
customer3.setAddress("深圳");
entityManager.persist(customer3);
// 提交事务
transaction.commit();
// 释放资源
entityManager.close();
entityManagerFactory.close();
}
查看日志:
INFO: HHH000490: Using JtaPlatform implementation: [org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform]
Hibernate: insert into c_customer (c_address, c_age, c_name, c_phone, c_sex) values (?, ?, ?, ?, ?)
Hibernate: insert into c_customer (c_address, c_age, c_name, c_phone, c_sex) values (?, ?, ?, ?, ?)
Hibernate: insert into c_customer (c_address, c_age, c_name, c_phone, c_sex) values (?, ?, ?, ?, ?)
根据 id 查询操作
find
方法实现(立即查询) /**
* 运行之前,修改hibernate.hbm2ddl.auto=update
* 立即查询操作
*/
@Test
public void testQuery1() {
// 获取实体管理器工厂
EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("myJpa");
// 获取实体管理器
EntityManager entityManager = entityManagerFactory.createEntityManager();
// 获取事务
EntityTransaction transaction = entityManager.getTransaction();
// 开启事务
transaction.begin();
// 查询实体并输出
Customer customer = entityManager.find(Customer.class, 2L);
System.out.println(customer);
// 提交事务
transaction.commit();
// 释放资源
entityManager.close();
entityManagerFactory.close();
}
实际发送的SQL语句就是:select * from customer where id = 2
INFO: HHH000490: Using JtaPlatform implementation: [org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform]
Hibernate: select customer0_.id as id1_0_0_, customer0_.c_address as c_addres2_0_0_, customer0_.c_age as c_age3_0_0_, customer0_.c_name as c_name4_0_0_, customer0_.c_phone as c_phone5_0_0_, customer0_.c_sex as c_sex6_0_0_ from c_customer customer0_ where customer0_.id=?
Customer(Id=2, name=李四, age=20, sex=false, phone=13533333555, address=广州)
getReference
方法实现(懒加载查询)(推荐) /**
* 运行之前,修改hibernate.hbm2ddl.auto=update
* 延迟查询操作(查询结果对象的时候,才会发送查询的sql语句)
*/
@Test
public void testQuery2() {
// 获取实体管理器工厂
EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("myJpa");
// 获取实体管理器
EntityManager entityManager = entityManagerFactory.createEntityManager();
// 获取事务
EntityTransaction transaction = entityManager.getTransaction();
// 开启事务
transaction.begin();
// 查询实体并输出
Customer customer = entityManager.getReference(Customer.class, 2L);
System.out.println(customer);
// 提交事务
transaction.commit();
// 释放资源
entityManager.close();
entityManagerFactory.close();
}
日志发现与 find 查询没有区别:
INFO: HHH000490: Using JtaPlatform implementation: [org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform]
Hibernate: select customer0_.id as id1_0_0_, customer0_.c_address as c_addres2_0_0_, customer0_.c_age as c_age3_0_0_, customer0_.c_name as c_name4_0_0_, customer0_.c_phone as c_phone5_0_0_, customer0_.c_sex as c_sex6_0_0_ from c_customer customer0_ where customer0_.id=?
Customer(Id=2, name=李四, age=20, sex=false, phone=13533333555, address=广州)
可以注释打印对象在对比试试://System.out.println(customer)
;
INFO: HHH000490: Using JtaPlatform implementation: [org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform]
可以发现,如果没有使用对象的话,是没有调用查询SQL语句的
find
与getReference
查询对比:
find
实现的查询时,是会在调用 find 方法时,立即发送SQL语句查询数据库的操作getReference
是一种延迟加载策略的操作,调用getReference方法不会立即发送sql语句查询数据库,当调用查询结果对象的时候,才会发送查询的sql语句(实际就是动态代理)更新操作
/**
* 运行之前,修改hibernate.hbm2ddl.auto=update
* 更新操作
*/
@Test
public void testUpdate() {
// 获取实体管理器工厂
EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("myJpa");
// 获取实体管理器
EntityManager entityManager = entityManagerFactory.createEntityManager();
// 获取事务
EntityTransaction transaction = entityManager.getTransaction();
// 开启事务
transaction.begin();
// 查询实体并更新
Customer customer = entityManager.find(Customer.class, 2L);
customer.setAddress("上海");
entityManager.merge(customer);
// 提交事务
transaction.commit();
// 释放资源
entityManager.close();
entityManagerFactory.close();
}
查看日志:
INFO: HHH000490: Using JtaPlatform implementation: [org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform]
Hibernate: select customer0_.id as id1_0_0_, customer0_.c_address as c_addres2_0_0_, customer0_.c_age as c_age3_0_0_, customer0_.c_name as c_name4_0_0_, customer0_.c_phone as c_phone5_0_0_, customer0_.c_sex as c_sex6_0_0_ from c_customer customer0_ where customer0_.id=?
Hibernate: update c_customer set c_address=?, c_age=?, c_name=?, c_phone=?, c_sex=? where id=?
删除操作
/**
* 运行之前,修改hibernate.hbm2ddl.auto=update
* 删除操作
*/
@Test
public void testDelete() {
// 获取实体管理器工厂
EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("myJpa");
// 获取实体管理器
EntityManager entityManager = entityManagerFactory.createEntityManager();
// 获取事务
EntityTransaction transaction = entityManager.getTransaction();
// 开启事务
transaction.begin();
// 查询实体并删除
Customer customer = entityManager.find(Customer.class, 1L);
entityManager.remove(customer);
// 提交事务
transaction.commit();
// 释放资源
entityManager.close();
entityManagerFactory.close();
}
查看日志:
INFO: HHH000490: Using JtaPlatform implementation: [org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform]
Hibernate: select customer0_.id as id1_0_0_, customer0_.c_address as c_addres2_0_0_, customer0_.c_age as c_age3_0_0_, customer0_.c_name as c_name4_0_0_, customer0_.c_phone as c_phone5_0_0_, customer0_.c_sex as c_sex6_0_0_ from c_customer customer0_ where customer0_.id=?
Hibernate: delete from c_customer where id=?
为什么要抽取 JpaUtil 工具类?
由于EntityManagerFactory
是一个线程安全的对象(即多个线程访问同一个EntityManagerFactory
对象不会有线程安全问题),并且EntityManagerFactory
的创建极其浪费资源,所以在使用JPA编程时,我们可以对EntityManagerFactory
的创建进行优化,只需要做到一个工程只存在一个EntityManagerFactory
即可。
解决思路是通过静态代码的形式创建 EntityManagerFactory
JpaUtil.java
工具类/**
* 解决实体管理器工厂的浪费资源和耗时问题
* 通过静态代码块的形式,当程序第一次访问此工具类时,创建一个公共的实体管理器工厂对象
*
* 第一次访问getEntityManager方法:经过静态代码块创建一个factory对象,再调用方法创建一个EntityManager对象
* 第二次方法getEntityManager方法:直接通过一个已经创建好的factory对象,创建EntityManager对象
*/
public class JpaUtils {
private static EntityManagerFactory factory;
static {
//1.加载配置文件,创建entityManagerFactory
factory = Persistence.createEntityManagerFactory("myJpa");
}
/**
* 获取EntityManager对象
*/
public static EntityManager getEntityManager() {
return factory.createEntityManager();
}
}
public class JpaTest {
@Test
public void testSave() {
// 1.通过工具类获取实体类管理器
EntityManager em = JpaUtils.getEntityManager();
// 2.获取事务对象
EntityTransaction tx = em.getTransaction();
// 开启事务
tx.begin();
//3.完成增删改查操作:保存一个客户到数据库中
Customer customer = new Customer();
customer.setName("Yolo");
customer.setAddress("BeiJing");
//保存操作
em.persist(customer);
//4.提交事务
tx.commit();
//5.释放资源
em.close();
//因为工厂是公共的,不能关闭,不然其他线程将无法获取
//factory.close();
}
}
标签:inter 实体类 北京 保存数据 llb 完成 com persist int
原文地址:https://www.cnblogs.com/liusuixing/p/14265087.html