传智播客—hibernate关系映射 三(转载)
1).级联添加:
<set name="orders" cascade="save-update" lazy="false">
??? <key><column name="cid"></column></key>
??? <one-to-many class="cn.itcast.cc.hibernate.persistence.Order"/>
这个属性十分重要,涉及到hibernate缓存监控技术。(hibernate缓存监控技术在后面会有介绍)。Inverse属性使得,如果持久化对象一旦发生改变就自动更新数据表中的记录。(持久化对象后面会有介绍)通过load、save、update返回或设置的对象都是持久化对象,这些对象一起发生改变,比如set了一个新值,hibernate就会自动将新值更新到数据库中。当调用了session.close方法是,这些持久化对象就不存在了!
1.??????? new String()对象放在堆中。
2.??????? str放在栈中。
3.??????? 将str指向堆中的对象。
如:
1.??????? String str1 = new String();
2.??????? String str2 = str1;
3.??????? str1 = null;
4.??????? str2 = null;
请问放在堆中的对象何时被销毁?第三步吗?No!是第四步。这个对象从第1步“出生”,到第4步执行结束后“死亡”。
1.??????? 减少访问数据库的频率。
2.??????? 保证缓存中的对象与数据库中的记录保存同步。(监控技术)
3.??????? 当缓存中的持久化对象之间存在循环关联关系时,Session会保证不出现访问对象图的死循,还以及由死循环引起的JVM堆栈溢出异常。
监控技术是如何实现的?session保存在缓存中的持久化对象,实质上是保存了对象的引用。那么同时与这个引用对应一个持久化对象的clone对象。Session监控就是将持久化对象与在缓存中的clone对象进行对比,如果发生改变就自动对数据库进行相应的操作。这样就保持了持久化对象与数据库记录的同步。
?
Session在清理缓存时,按照以下顺序执行sql语句。
1.按照应用程序调用save()方法的先后顺序,执行所有的对实体进行插入的insert语句。
2.所有对实体进行更新的update语句。
3.所有对实体进行删除的delete语句。
4.所有对集合元素进行删除、更新或插入的sql语句。
5.执行所有对集合进行插入的insert语句。
6.按照应用程序调用delete()方法的先后执行。
默认情况下:
1.当应用程序commit()方法的时候,先清理缓存,然后在向数据库提交事务。
2.当调用find()或iterator()时,如果对象属性发生变化,会先清理缓存,以保证查询结果能够反映持久化对象的最新状态。
3.显式调用flush()。
?
Session的清理模式:“session.setFlushMode(FlushMode.AUTO);”
FlushMode.NEVER 模式受主键影响,当主键为identity时,受底层数据库影响所以NEVER无效。如果为increment时,由于这个主键不受底层数据库的影响,所以NEVER有效!
?
清理方法:
Session.flush();//清理、刷出数据库与缓存同步,但不提交事务。
Session.refresh();//刷新。让缓存与数据库同步。
Session.clear();//清空。清空缓存中的引用。
临时状态(transient):用new语句创建,没有被持久化(没有调用Session对方法),不处于session中,该对象成为临时对象。
持久化状态(persistent):已经被持久化,加入到session的缓存中。该状态的对象为持久化对象。
游离状态(detached):已经被持久化,但不处于session中(seesion清空或被delete)。该状态的对象为游离对象。
l????????? 不处于session中,不被任何session关联。
l????????? 数据库中没有对应的记录。
l????????? 以下情况,对象进入临时状态:
1.????????? new语句刚创建了一个对象。
2.????????? session的delete方法使持久化对象或游离对象转变为临时对象,对于游离对象,该方法从数据库中删除记录,对于持久化对象,该方法从数据库中删除记录,还要删除缓存中的对象。
临时对象判断法:
1.OID为null。
2.具有version属性并取值为null。
3.在映射文件中为<id>元素设置了unsaved-value属性,并且OID属性取值与属性匹配。
4.在映射文件中为<version>元素设置了unsaved-value属性,并且version属性取值与属性匹配。
5.自定义了Interceptor实现类,并且isUnsaved方法返回Boolean.true。如果id的类型为long,则默认值为0,此时需要在配置文件中设置id的unsaved-value为0。
l????????? 位于一个session缓存中,总是被一个session关联。
l????????? 持久化对象和数据库记录相对应。
l????????? 清理缓存时,会根据对象属性变化,同步更新数据库。
l????????? save把临时对象转变为持久化对象。
l????????? load或find或get返回的对象总是持久化状态。
l????????? find方法返回的list存放的都是持久化对象。
l????????? update、save、SaveOrUpdate和Lock方法使游离对象装变为持久化对象。
?
????????? 在实际的应用程序中应该避免一个java对象被多个session实例关联,会导致重复执行sql语句,并且极容易出现一些并发问题。
l????????? 不再位于session的缓存中,游离对象不被session关联。
l????????? 游离对象由持久化转变过来的,因此在数据库中可能还存在与它对应的记录(前提条件是没有其他程序删除了这条记录)。
l????????? close方法使缓存被清空,缓存中的所有的对象都变为游离对象。如果没有引用他们的话,他们就会结束生命周期。
l????????? evict方法从缓存中删除一个持久化对象,使他变为游离态对象。当缓存中保存了大量的持久????? 化对象时,会消耗许多内存空间,使用该方法删掉一些对象来节省空间。
?
l????????? 对象加入缓存,成为持久化对象。
?
2). update:
l????????? 将游离对象转变为持久化对象。不论对象属性是否发生变化,该方法都会执行update操作。如果希望仅当属性变化时才执行update语句的话可进行如下配置:
? ?????????????? <class name=“…”
??????????? table=“…”
??????????? select-before-update=“true”>?
3). saveOrUpdate:
l????????? 该方法同时包含save和update方法,如果参数是临时对象就用save方法,如果是游离对象就用update方法,如果是持久化对象就直接返回。
?
4) .load和get:
l????????? 从数据库加载指定的OID持久化对象。
l????????? 如果数据库中不存在该记录时,load方法会抛出异常,而get方法返回null。
?
5). delete
l????????? 如果参数是持久化对象,就执行一个delete语句。若为游离对象,先使游离对象被session关联,使他变为持久化对象,然后计划执行一个delete语句。
?
Session的update操作方法盲目的激活触发器,如果游离状态的对象的属性和数据库一致,则更新操作是多余的。
<spa