hibernate5操纵对象入门[3]操控对象封装方法

Posted jeanheo

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hibernate5操纵对象入门[3]操控对象封装方法相关的知识,希望对你有一定的参考价值。

为什么要说是“封装方法”呢?因为它帮我们封装好了底层的增删改查操作,直接调用相应方法即可灵活地操作我们数据库数据。它们由Session接口提供,下面我们通过实例一一分析这些方法。

1.save方法

Session 的 save() 方法使一个临时对象转变为持久化对象
Session 的 save() 方法完成以下操作:
1. 把 User对象加入到 Session 缓存中,使它进入持久化状态
2. 选用映射文件指定的标识符生成器,为持久化对象分配唯一的 OID。在 使用代理主键的情况下,setId() 方法为 User对象设置 OID 是无效的。
3. 计划在 flush 缓存的时候,执行一条 insert 语句。

注意:
1. Hibernate 通过持久化对象的 OID 来维持它和数据库相关记录的对应关系。当 User 对象处于持久化状态时,不允许程序随意修改它的 ID,否则会报异常:org.hibernate.HibernateException: identifier of an instance of com.zeng2.model.User was altered from 17(持久化状态的原有值) to 100(新修改的值)

所以在实际开发中,我们应该将setId()设为private防止用户更改实体id
2. 在一般完成持久化对象的初始化工作时,我们应先完成资源准备(设定成员属性值)后,再调用save方法。否则会增加额外的sql语句,如下所示:

//先设值再保存
User user1 = new User();
user1.setName("name1");
session.save(user1);
//Hibernate: insert into t_user2 (name, id) values (?, ?)
//先保存再设值
User user2 = new User();
session.save(user2);
user2.setName("name2");
//Hibernate: insert into t_user2 (name, id) values (?, ?)
//Hibernate: update t_user2 set name=? where id=? update t_user2 set name=? where id=?

2. persist方法

persist和save都能用来持久化对象,但它和user的区别是:当对一个 OID 不为 Null 的对象执行 save() 方法时,会把该对象以一个新的 oid 保存到数据库中;但执行 persist() 方法时会抛出一个异常。

//测试persist和save的区别
User user = new User();
user.setId(100);
session.save(user);
//执行Hibernate: insert into t_user2 (name, id) values (?, ?)
User user2 = new User();
user2.setId(200);
session.persist(user2);
//报异常org.hibernate.PersistentObjectException: detached entity passed to persist: com.zeng2.model.User

3. get和load方法

  1. 相同点:
    都可以根据跟定的 OID 从数据库中加载一个持久化对象
  2. 区别:
    1. 当数据库中不存在与 OID 对应的记录时,load() 方法抛出 ObjectNotFoundException 异常,而 get() 方法返回 null。
    2. 两者采用不同的延迟检索策略:load默认使用懒加载策略,除非将相应对象的获取策略设为即时加载。而get只要调用了,都会立即从数据库中甲在数据。

4. update方法

使一个游离对象转变为持久化对象,并且计划在flush时执行一条 update 语句
在一下情况使用会抛出异常:
1. 当 update() 方法关联一个游离对象时,如果在 Session 的缓存中已经存在相同 OID 的持久化对象,会抛出异常
2. 当 update() 方法关联一个游离对象时,如果在数据库中不存在相应的记录,也会抛出异常.
下面是我们的测试代码:

//测试update
User user = new User();
session.update(user);
//报异常:org.hibernate.TransientObjectException: The given object has a null identifier: com.zeng2.model.User
User user = new User();
user.setId(1);//数据库中存在的id
session.update(user);
//Hibernate: update t_user2 set name=? where id=?
User user = new User();
user.setId(111111);//数据库中不存在的id
session.update(user);
//报异常:org.hibernate.StaleStateException: Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1
User user = session.get(User.class, 1);
User user2 = new User();
user2.setId(1);
session.update(user2);//更新一个在session缓存中已存在的对象
//报异常:org.hibernate.NonUniqueObjectException: A different object with the same identifier value was already associated with the session : [com.zeng2.model.User#1]

5. saveOrUpdate方法

Session 的 saveOrUpdate()可以看成是save和update的整合,两者形成有效互补。
它的执行过程吐下图所示:

Created with Raphaël 2.1.0 saveOrUpdate对象 游离对象(yes),临时对象(no) 更新对象 保存对象 yes no

以上是关于hibernate5操纵对象入门[3]操控对象封装方法的主要内容,如果未能解决你的问题,请参考以下文章

Hibernate5--课程笔记1

java 入门--面向对象初探

Hibernate入门教程

Hibernate5配置与使用具体解释

moon 一切皆对象

Hibernate入门