侧边栏壁纸
博主头像
张种恩的技术小栈博主等级

行动起来,活在当下

  • 累计撰写 748 篇文章
  • 累计创建 65 个标签
  • 累计收到 39 条评论

目 录CONTENT

文章目录

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

zze
zze
2019-10-19 / 0 评论 / 0 点赞 / 468 阅读 / 3471 字

不定期更新相关视频,抖音点击左上角加号后扫一扫右方侧边栏二维码关注我~正在更新《Shell其实很简单》系列

保存

// 定义对象
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
JPA

评论区