通过Hibernate 操作对象(上)

1.Session的缓存

只要Session实例没有结束生命周期,存放在它缓存中的对象也不会结束生命周期。

1.1.Session缓存的作用

(1)减少访问数据库频率;

(2)当缓存中的持久化对象之间存在循环关联关系时,Session会保证不出现访问对象图的死循环,以及由死循环引起的JVM堆栈溢出异常;

(3)保证数据库中的相关记录与缓存中的相应对象保持同步。

1.2.清理缓存机制

当Session缓存中对象的属性每次发生了变化,Session并不会立即清理缓存以及执行相关的SQL update语句,而是在特定的时间点才清理缓存。

默认情况下,Session会在以下时间点清理缓存:

(1)应用程序调用Transaction的commit()方法;

(2)应用程序执行一些查询操作时,若缓存中持久化对象的属性已发生变化,会清理缓存,保证查询结果正确;

(3)应用程序显式调用Session的flush()方法。

Transaction的commit()方法与Session的flush()方法的区别:

flush()方法进行清理缓存的操作,执行一系列的SQL语句,但不会提交事务;commit()方法会先调用flush()方法,然后提交事务。

例外情况:

若对象使用native生成器来生成OID,当调用Session的save()方法保存该对象时,会立即执行insert语句。

若不想Session在默认的时间点清理缓存,可以通过Session的setFlushMode()方法显式设定清理缓存的时间点。

三种清理模式:

            模式                        各种查询方法       Transaction的commit()       Session的flush()

FlushMode.AUTO(默认)         清理                          清理                                清理

FlushMode.COMMIT             不清理                       清理                                清理

FlushMode.NEVER                不清理                       不清理                             清理

2.Java对象在Hibernate持久化层的状态

临时状态(transient):刚用new语句创建,还没有被持久化,并且不处于Session缓存中;

持久化状态(persistent):已被持久化,并且加入到Session的缓存中;

游离状态(datached):已被持久化,但不处于Session缓存中;

删除状态(removed):不处于Session缓存中,并且Session已经计划将其从数据库中删除;

同一个Session实例的缓存,数据库表中的每条记录只对应唯一的持久化对象。

3.Session接口的用法

3.1.Session的save()和persist()方法

Session的save()和persist()方法均使一个临时对象转变为持久化对象,并计划执行一条insert语句。

Customer customer = new Customer();

customer.setId(new Long(9));

customer.serName("Tom");

Session session = sessionFactory.openSession();

Transaction tx = session.beginTransaction();

session.save(customer);    //计划执行insert

tx.commit();    //真正执行insert

session.close();


若使用代理主键(如increment)而非自然主键的情况下,setId()方法为临时变量设置OID是无效的。

save()方法并不会立即执行insert语句,只有当Session清理缓存时,才会执行insert语句。

save()方法是用来持久化一个临时变量的,不应该把持久化对象或游离对象传递给save()方法,否则会使操作多余,或导致数据库表中存在多条代表相同业务实体的记录。

Customer customer = new Customer();

Session session = sessionFactory.openSession();

Transaction tx = session.beginTranasaction();

session.save(customer);

customer.setName("Tom");

session.save(customer);    //多余操作

tx.commit();

Customer customer = new Customer();

customer.setName("Tom");

Session session1 = sessionFactory.openSession();

Transaction tx1 = session1.beginTranasaction();

session1.save(customer);    //ID为1

tx1.commit();

session1.close();     //Customer对象变为游离对象

Session session2 = sessionFactory.openSession();

Transaction tx2 = session2.beginTranasaction();

session2.save(customer);    //ID为2

tx2.commit();

session2.close();

persist()与save()的不同之处:

persist()方法不保证立即为持久化对象的OID赋值,而是可能在Session清理缓存时才为OID赋值;

如果在事务边界以外调用persist()方法,那么该方法不会计划执行insert语句。

3.2.Session的load()和get()方法

Session的load()和get()方法都能根据给定的OID从数据库中加载一个持久化对象,但当数据库中不存在与OID对应的记录时,load()方法抛出ObjectNotFoundException,get()方法返回null。

load()方法会根据<class>元素的lazy属性值"true"或"false"(默认为"true"),采取延迟或立即检索策略,get()总是采用立即检索策略。

3.3.Session的update()方法

Session的update()方法使一个游离对象转变为持久化对象,并计划执行一条update语句。

Customer customer = new Customer();

customer.setName("Tom");

Session session1 = sessionFactory.openSession();

Transaction tx1 = session1.beginTranasaction();

session1.save(customer);

tx1.commit();

session1.close();    //Customer对象变为游离对象

Session session2 = sessionFactory.openSession();

Transaction tx2 = session2.beginTranasaction();

customer.setName("Jack");

customer.serName("Linda");

session2.update(customer);    //计划执行update

tx2.commit();    //真正执行update

session2.close();

Session只有在清理缓存时才会执行update语句。即使程序中多次修改了对象的属性,在清理缓存时也只会执行一次update语句。

只有通过update方法使游离对象被一个Session关联,即使没有修改该对象的任何属性,Session在清理缓存时也会执行update语句。

如果希望Session仅当修改了对象的属性时,才执行update语句,可以把<class>元素的select-before-update设为true。

3.4.Session的saveOrUpdate()方法

Session的saveOrUpdate()方法同时包含了save()与update()方法的功能,如果传入的参数是临时变量,就调用save()方法;如果传入的参数是游离对象,就调用update()方法;如果传入的是持久化对象,就直接返回。

3.5.Session的delete()方法

Session的delete()方法用于从数据库中删除一个对象。

Session只有在清理缓存时才会执行delete语句。

Session的delete()方法一次只能删除一个对象。

3.6.Session的merge()方法

Session的merge()方法能够把一个游离对象的属性复制到一个持久化对象中。

3.7.Session的replicate()方法

Session的replicate()方法能够把一个数据库中的对象复制到另一个数据库中。

session.replicate(object,ReplicationMode.LATEST_VERSION);

第二个参数决定复制模式:

ReplicationMode.IGNORE:若目标数据库存在OID相同的对象,就什么也不做;

ReplicationMode.OVERWRITE:若目标数据库中存在OID相同的对象,就覆盖已存在的对象;

ReplicationMode.EXCEPTION若目标数据库中存在OID相同的对象,就抛出异常;

ReplicationMode.LATEST_VERSION若目标数据库中存在OID相同的对象,就比较两者的版本,保存新版本的数据。

4.操作级联对象

对象-关系映射文件中,用于映射持久化类之间关联关系的元素,如<set>、<many-to-one>等,都有一个cascade属性,用来指定如何操作与当前对象关联的其他对象。

cascade属性值:

none                  cascade的默认值,Session操作当前对象时,忽略其他关联对象;

save-update        通过Session的save()、update()、saveOrUpdate()方法保存或更新当前对象时,级联保存所有与之关联的

                            临时对象,级联更新所有与之关联的游离对象;

persist                通过Session的persist()方法保存当前对象时,级联保存所有与之关联的临时对象;

merge                 通过Session的merge()方法融合当前对象时,级联融合所有与之关联的游离对象;

delete                 通过Session的delete()方法删除当前对象时,级联删除所有与之关联的对象;

lock                    通过Session的lock()方法把当前游离对象加入到Session缓存中时,把所有与之关联的游离对象也加入

                             到Session缓存中;

replicate              通过Session的replicate()方法复制当前对象时,级联复制所有与之关联的对象;

evict                   通过Session的evict()方法从Session缓存清除当前对象时,级联清除所有与之关联的对象;

refresh                通过Session的refresh()方法刷新当前对象时,级联刷新所有与之关联的对象;

all                       包含save-update、persist、merge、delete、lock、replicate、evict及refresh的行为;

delete-orphan       删除所有与当前对象解除关联关系的对象;

all-delete-orphan   包含all和delete-orphan的行为。

5.更新数据库对象的两种方式

(1)先加载持久化对象,修改持久化对象的属性,然后Session清理缓存时自动同步更新数据库中的相应数据:

Session session = sessionFactory.openSession();

Transaction tx = session.beginTransaction();

Customer customer = (Customer)session.get(Customer.class,new Long(9));

customer.setName("Jack");    //修改name属性

tx.commit();    //更新数据库

session.close();    //customer变为游离对象

(2)更新游离对象,然后通过Session的update()方法更新数据库中的相应数据:

Customer customer = ... //假定customer为游离对象

customer.serName("Tom");

Session session = sessionFactory.openSession();

Transaction tx = session.beginTransaction();

session.update(customer);    //计划执行update

tx.commit();    //真正执行update,更新数据库

session.close();

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值