侧边栏壁纸
博主头像
张种恩博主等级

一个能运维的 JPG 搬运工

  • 累计撰写 709 篇文章
  • 累计创建 62 个标签
  • 累计收到 27 条评论

目 录CONTENT

文章目录

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

张种恩
2019-10-19 / 0 评论 / 0 点赞 / 292 阅读 / 0 字 / 正在检测是否收录...
温馨提示:
本文最后更新于 2020-02-25,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

保存

// 定义对象
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();
}
0

评论区