JPA(5)之完成增删改查操作

JPA(5)之完成增删改查操作

微信搜索 zze_coding 或扫描 👉 二维码关注我的微信公众号获取更多资源推送:

保存

// 定义对象
Customer c = new Customer();
c.setCustName("阿里巴巴");
c.setCustLevel("VIP客户");
c.setCustSource("网络");
c.setCustIndustry("电商平台");
c.setCustAddress("浙江省");
c.setCustPhone("011-888888");
EntityManager em = null;
EntityTransaction tx = null;
try {
    // 获取实体管理对象
    em = JPAUtil.getEntityManager();
    // 获取事务对象
    tx = em.getTransaction();
    // 开启事务
    tx.begin();
    // 执行操作
    em.persist(c);
    // 提交事务
    tx.commit();
} catch (Exception e) {
    // 回滚事务
    tx.rollback();
    e.printStackTrace();
} finally {
    // 释放资源
    em.close();
}

修改

//定义对象
EntityManager em=null;
EntityTransaction tx=null;
try{
    //获取实体管理对象
    em=JPAUtil.getEntityManager();
    //获取事务对象
    tx=em.getTransaction();
    //开启事务
    tx.begin();
    //执行操作
    Customer c1 = em.find(Customer.class, 3L);
    c1.setCustName("淘宝巴巴");
    em.clear();//把c1对象从缓存中清除出去
    em.merge(c1);
    //提交事务
    tx.commit();
}catch(Exception e){
    //回滚事务
    tx.rollback();
    e.printStackTrace();
}finally{
    //释放资源
    em.close();

在上述示例中,为啥执行 merge 方法之前还执行了 clear 方法?
首先,我们已经知道上述 JPA 使用的实现是 Hiberante,而 Hibernate 是存在一级缓存的,在更新之前会将要更新的内容与一级缓存中的内容作对比,如果有变化才在事务提交的时候真正的执行更新操作将变化部分更新到 DB(关于 Hibernate 部分详细可参考Hibernate 系列) 。
此时就有一种情况,在查询的对象进入一级缓存后并且在事务提交之前,如果查询对象对应的行在 DB 中已经发生了变化,那么一级缓存中的对象此时与 DB 中就是不同步的,此时如果继续使用这个缓存对象与要更新的对象作对比,数据差异肯定是不准确的(脏读)。
为避免上述描述的这种情况,EntityManager 对象给我们提供了 clear 方法,该方法的作用就是清空一级缓存中的已缓存的对象,这样在更新时 Hibernate 就会即时从 DB 查询最新的内容封装为对象再次放到一级缓存,然后立即与要更新的对象进行对比检查,最后执行更新操作,保证了对象在更新时一级缓存中的内容与 DB 中数据的一致性。
所以如果不考虑脏读情况,那么上述 clear 方法是可以省略的。

删除

// 定义对象
EntityManager em = null;
EntityTransaction tx = null;
try {
    // 获取实体管理对象
    em = JPAUtil.getEntityManager();
    // 获取事务对象
    tx = em.getTransaction();
    // 开启事务
    tx.begin();
    // 执行操作
    Customer c1 = em.find(Customer.class, 1L);
    em.remove(c1);
    // 提交事务
    tx.commit();
} catch (Exception e) {
    // 回滚事务
    tx.rollback();
    e.printStackTrace();
} finally {
    // 释放资源
    em.close();
}

根据id查询

使用立即加载策略

// 定义对象
EntityManager em = null;
EntityTransaction tx = null;
try {
    // 获取实体管理对象
    em = JPAUtil.getEntityManager();
    // 获取事务对象
    tx = em.getTransaction();
    // 开启事务
    tx.begin();
    // 执行操作
    Customer c1 = em.find(Customer.class, 3L);
    // 提交事务
    tx.commit();
    System.out.println(c1); // 输出查询对象
} catch (Exception e) {
    // 回滚事务
    tx.rollback();
    e.printStackTrace();
} finally {
    // 释放资源
    em.close();
}

使用延迟加载策略

// 定义对象
EntityManager em = null;
EntityTransaction tx = null;
try {
    // 获取实体管理对象
    em = JPAUtil.getEntityManager();
    // 获取事务对象
    tx = em.getTransaction();
    // 开启事务
    tx.begin();
    // 执行操作
    Customer c1 = em.getReference(Customer.class, 3L);
    // 提交事务
    tx.commit();
    System.out.println(c1);
} catch (Exception e) {
    // 回滚事务
    tx.rollback();
    e.printStackTrace();
} finally {
    // 释放资源
    em.close();
}

Copyright: 采用 知识共享署名4.0 国际许可协议进行许可

Links: https://www.zze.xyz/archives/jpa5.html

Buy me a cup of coffee ☕.