Hibernate之session接口(二)

Hibernate之session接口(二)_第1张图片

1.对象的几种状态

在所有之前,说明一下,对于hibernate,它的对象有三种状态,transient、persistent、detached

下边是常见的翻译办法:

transient:瞬时态或者临时态

(new DeptPo(1,”行政部”,20,”行政相关”),该po的实例和session没有关联,该po的实例处于transient)

persistent:持久化状态

(和数据库中记录想影射的Po实例,它的状态是persistent, 通过get和load等得到的对象都是persistent)

detached:脱管状态或者游离态

(1)当通过get或load方法得到的po对象它们都处于persistent,但如果执行delete(po)时(但不能执行事务),该 po状态就处于detached, (表示和session脱离关联),因delete而变成游离态可以通过save或saveOrUpdate()变成持久态

(2)当把session关闭时,session缓存中的persistent的po对象也变成detached

因关闭session而变成游离态的可以通过lock、save、update变成持久态

持久态实例可以通过调用 delete()变成游离状态。

通过get()或load()方法得到的实例都是持久化状态的。

游离状态的实例可以通过调用lock()或者replicate()进行持久化。

save()和persist()将会引发SQL的INSERT,delete()会引发SQLDELETE,

而update()或merge()会引发SQL UPDATE。对持久化(persistent)实例的修改在刷新提交的时候会被检测到,它也会引起SQL UPDATE。

saveOrUpdate()或者replicate()会引发SQLINSERT或者UPDATE

可以通过session提供的方法用于改变对象的状态。

save()方法:

1.使一个临时对象成为持久化对象。

2.为对象分配ID。

3.在 flush缓存的时候发送一条insert语句。

4.save之前设置的ID是无效的。

5.持久化对象的ID是不可修改的。

@Test

public void testSave() {

News news = new News();

news.setAuthor("wenyu2");

news.setDate(new Date());

news.setTitle("php");

news.setId(23);//该行设置无效

System.out.println(news);

session.save(news);

System.out.println(news);

news.setId(45);//改行抛出异常。

persist()方法:

与save方法类似的是persist()方法, persist()方法也可以执行insert操作,但是跟save的区别是,若在persist之前设置了ID值, 则抛出异常,不会insert操作。

@Test

public void testPersist() {

News news = new News();

news.setAuthor("wangwu");

news.setDate(new Date());

news.setTitle("py");

news.setId(34);//抛异常,不会执行insert操作。

session.persist(news);

}

get()方法:该方法会立即查询加载数据库中的对象(立即执行select语句)。但是若是该记录在数据库中不存在那么返回一个null(没有即没有很直接)。

@Test

public void testGet() {

News news = (News) session.get(News.class, 4);

session.close();//若是手动关闭session,下面的打印也会成功。

System.out.println(news);

}

Load()方法:该方法功能和get相同,但是属于延迟加载的方法。

也就是说,执行load方法之后,若是不使用该对象那么不会执行select语句,仅仅返回一个代理对象。与此同时若是查询的记录在数据库中不存在,那么会抛出异常(找不到对象),可以理解为返回代理对象之后,该代理对象无法找到与之匹配的真实对象,即抛异常。

若是在使用对象之前手动关闭了session,在使用对象的时候会抛出懒加载异常。而get却是可以打印出来。

@Test

public void testLoad() {

News news = (News) session.load(News.class, 4);

System.out.println(news.getClass().getName());

session.close();

System.out.println(news);//调用的时候抛出懒加载异常。

}

update方法:

1.若更新一个持久化对象,不需要显示的调用update方法,因为在Transaction 的commit方法之前会先执行flush操作(出发update语句)。

2.当session关闭或者执行了evict方法,将对象从session 缓存中移除,那么该对象处于游离状态,此时需要显示调用update()方法,这个update()显示调用的时候,不论对象的属性是否发生变化都会执行update语句,在跟触发器协同工作的时候,为了避免这个问题,我们可以使用在hbm.xml文件中设置select-before-date值为true,检测是否有改变,若是没有改变那么不会发送update语句。(该方式不常用)。

若数据表中没有该记录,但是还是执行update的话,会导致异常。

当update方法关联一个游离状态的对象时,如果session中已经存在相同ID的持久化对象,会抛异常,因为session 中不能存在两个OID相同的对象。

@Test

public void testUpdate() {

News news = (News) session.get(News.class, 4);

transaction.commit();

session.close();// 至此news对象是一个游离状态的。

// news.setId(6);//该行会抛异常,ID在数据表中不存在。

session = sessionFactory.openSession();

transaction = session.beginTransaction();

// news.setAuthor("JDBC");// news既不在原来的session缓存中,也不在新的缓存中。

// News news2=(News)session.get(News.class, 5);//

session.update(news);// 也就是需要通过显示的执行update方法,将该对象变为持久状态。

}

saveOrUpdate()方法:

根据是否有OID 来判断是采用save操作还是update操作。 若OID不为空但是没有对应的记录,会抛异常。

@Test

public void testSaveOrUpdate() {

News news = (News) new News("FF", "ff", new Date());

news.setId(34);//若该ID在数据库中没有对应的记录,抛异常。

session.saveOrUpdate(news);

}


delete方法:

可删除一个游离对象,也可以删除一个持久化对象。session 的delete方法处理过程:

计划执行一条delete语句,把对象从session缓存中删除,该对象成为删除状态。

hibernate.use.identifier.rollback属性,默认值为false,若设置为true,将改变delete行为,那么会把对象的OID置为空,成为临时对象。

@Test

public void testDelete() {

News news = (News) session.get(News.class, 11);

session.delete(news);

// session.update(news);//删除状态的不可以进行update操作。

System.out.println(news);

}


Evict()方法:

@Test

public void testEvict() {

News news1 = (News) session.get(News.class, 9);

News news2 = (News) session.get(News.class, 8);

news1.setTitle("uu");

news2.setTitle("mm");

session.evict(news2);// 从缓存中移除对象,该对象成为游离状态对象。

session.update(news2);// 该对象若是要update的话,需要显示的调用,因为该对象已经属于游离对象。

}

你可能感兴趣的:(Hibernate之session接口(二))