注册 | 登录
|||
1. Session缓存
为了让对象A一直处于生命周期中,要么对象A被显示引用,要么对对象A的引用保存在始终处于生命周期中的对象B中,直到对象B的生命周期结束而结束。在Session接口的实现中包含了一系列的Java集合,这些集合用于保存对持久化对象的引用,因此这些Java集合就构成了Session的缓存。
当调用Session接口的save()方法持久化一个对象时,该对象被加入到Session缓存中,以后只要Session缓存没有被清空,该对象将一直处于生命周期中。
当调用Session接口的get()方法试图装载一个持久化对象时,Session首先判断缓存中是否存在这个对象,若存在则返回,若不存在则从数据库中检索。
2. Session缓存的作用
(1) 减少访问数据库的频率。应用程序从缓存中读取持久化对象的速度显然优于从数据库中检索数据的速度。
(2) 当缓存中的持久化对象之间存在循环关联关系时,Session会保证不出现访问对象图的死循环,以及由死循环引发的JVM堆栈溢出。
(3) 保证数据库中的相关记录与缓存中的记录同步。Session在清理缓存的时,会自动进行脏数据检查(dirty-check),如果发现Session缓存中的对象与数据库中相应记录不一致,则会按最新的对象属性更新数据库。
3. 清理缓存的机制
为减少访问数据库的次数,当Session缓存中对象的属性发生变化时,并不会及时清理缓存及执行相关的SQL Update语句,而是在特定的时间点把相关的SQL合并为一条SQL语句才清理缓存。
Transaction transaction = hibernateSession.beginTransaction();
Customers c = (Customers)hibernateSession.get(Customers.class, new Long(3));
c.setName("Mike");
c.setName("Jone");
transaction.commit();//自动清理缓存,执行一条Update语句,提交事务
在默认情况下,Session会在以下时间点清理缓存(保证Session缓存中对象与数据库记录数据的一致性。):
(1) org.hibernate.Transaction.commit():先清理缓存再提交事务;
(2) 执行持久化查询操作时,如果缓存中的持久化对象的属性已发生变化,则先清理缓存以便与数据库中的记录保持同步;
(3) 显示调用Session.flush()时,会清空缓存。
Transaction transaction = hibernateSession.beginTransaction();
Customers c = (Customers)hibernateSession.get(Customers.class, new Long(3));
c.setName("ChengDong");
hibernateSession.flush();// 显示清理缓存,执行update语句
c.setName("Mike");
transaction.commit();// 自动清理缓存,执行update语句,提交事务
注意:commit()和flush()方法区别在于:后者进行清理缓存的操作,执行一系列SQL语句,但不会提交事务;前者会先调用flush()方法,然后提交事务。提交事务也就意味着对数据库所做的
更新将永久保存下来。
除了默认的清理缓存的方式外,还可以通过Session.setFlushMode()方法显示设定清理缓存的时间点,包括FlushMode.AUTO、FlushMode.NEVER、FlushMode.COMMIT,具体用法详查资料。
4. Java对象在持久化层的状态:
(1) Transient(临时状态):new语句创建、没有被持久化且不在Session缓存中。处于这种状态的对象被称为临时对象;
(2) Persistent(持久化状态):已被持久化且已加入到Session缓存中。处于这种状态的对象被称为持久化对象;
(3) Detached(游离状态):已被持久化,但不处于Session的缓存中。处于这种状态的对象被称为游离对象。
持久化对象的特征:
(1) OID不为NULL;
(2) 位于一个Session实例的缓存中;
(3) 持久化对象与数据库中的相关记录对应;
(4) Session在清理缓存时,会根据持久化对象的属性变化来同步更新数据库。
Session的许多方法都能使Java对象进入持久化状态:
(1) save():临时对象---> 持久化对象;
(2) load()/get():返回的对象总是处于持久化状态;
(3) list():返回的list对象都是持久化对象;
(4) update()/saveOrUpdate()/lock():游离对象--->持久化对象。
Hibernate保证同一个Session实例的缓存中,数据库中的每条记录只对应唯一的持久化对象,因此来自于同一个session实例缓存中的持久化对象的引用变量必然相同,即:
Session hibernateSession = sessionFactory.openSession();
Session hibernateSession2 = sessionFactory.openSession();
Transaction transaction = hibernateSession.beginTransaction();
Transaction transaction2 = hibernateSession2.beginTransaction();
Customers a = (Customers)hibernateSession.get(Customers.class, new Long(3));
Customers b = (Customers)hibernateSession.get(Customers.class, new Long(3));
Customers c = (Customers)hibernateSession2.get(Customers.class, new Long(3));
// 同一Session实例的缓存中仅存在唯一一个与数据库记录对应的持久化对象
System.out.println(a == b);// true
System.out.println(a == c);// false
transaction.commit();
transaction2.commit();
hibernateSession.close();
hibernateSession2.close();
在实际应用中,应避免一个Java对象同时位于多个Session实例中缓存中,否则这会导致重复执行SQL语句,并且极易出现高并发问题。
5. Session的一些持久化操作
(1) save
该操作首先将临时对象转化为持久化对象,并加入到Session缓存中;其次根据映射文件中给定的标识符生成器,为持久化对象分配唯一一个OID。save()方法仅用来持久化临时对象,在程序中不应该把持久化对象和游离对象传给save()。
注:save()操作仅仅是将Java对象的临时状态转化为持久化状态,并未立即执行insert语句,待需要清理缓存时才会执行insert语句。如果在save()方法改变了持久化对象的属性,则在清理缓存时不仅要执行insert语句,还要执行update语句,例如:
Transaction trasaction = session.beginTransaction();
Customers c = new Customers();
c.setName("testSave");
session.save(c);// 此步完成对象持久化和持久化对象OID的分配
c.setName("testCache");
trasaction.commit();// 自动清理缓存
控制台打印的SQL为:
Hibernate: insert into customers (name, ID) values (?, ?)
Hibernate: update customers set name=? where ID=?
(2) Session的get()和load()方法
这两个操作都是根据OID单数据加载持久化对象。它们的不同之处在于:当数据库中不存在与OID对应的记录时,load()会直接抛出org.hibernate.ObjectNotFoundException,而get()则返回null。
Archiver| 手机版| 科学网 ( 京ICP备07017567号-12 )
GMT+8, 2024-6-20 23:42
Powered by ScienceNet.cn
Copyright © 2007- 中国科学报社
哆哆女性网我靠学习走上人生巅峰美容院起名比较旺的字有哪些600086东方金钰合肥车管所超级武神华工科技园聊斋之灯草和尚崔字起名男宝宝名字大全铁臂阿童木游戏过道小范围吊顶psp幻想传说男孩起名杨金什么名字可圈可点的意思烧烤店咋起名字笔画与起名我要我的滋味汽车销售公司起名三个字测试起名吉凶女孩子的起名大全公司起名顺个口给美容公司起什么名字好薛男孩起名大全二个字无常劫姓顾的男生起名duowan.com嗨辣dxlive超市策划公司suo水厂起名什么名字淀粉肠小王子日销售额涨超10倍罗斯否认插足凯特王妃婚姻不负春光新的一天从800个哈欠开始有个姐真把千机伞做出来了国产伟哥去年销售近13亿充个话费竟沦为间接洗钱工具重庆警方辟谣“男子杀人焚尸”男子给前妻转账 现任妻子起诉要回春分繁花正当时呼北高速交通事故已致14人死亡杨洋拄拐现身医院月嫂回应掌掴婴儿是在赶虫子男孩疑遭霸凌 家长讨说法被踢出群因自嘲式简历走红的教授更新简介网友建议重庆地铁不准乘客携带菜筐清明节放假3天调休1天郑州一火锅店爆改成麻辣烫店19岁小伙救下5人后溺亡 多方发声两大学生合买彩票中奖一人不认账张家界的山上“长”满了韩国人?单亲妈妈陷入热恋 14岁儿子报警#春分立蛋大挑战#青海通报栏杆断裂小学生跌落住进ICU代拍被何赛飞拿着魔杖追着打315晚会后胖东来又人满为患了当地回应沈阳致3死车祸车主疑毒驾武汉大学樱花即将进入盛花期张立群任西安交通大学校长为江西彩礼“减负”的“试婚人”网友洛杉矶偶遇贾玲倪萍分享减重40斤方法男孩8年未见母亲被告知被遗忘小米汽车超级工厂正式揭幕周杰伦一审败诉网易特朗普谈“凯特王妃P图照”考生莫言也上北大硕士复试名单了妈妈回应孩子在校撞护栏坠楼恒大被罚41.75亿到底怎么缴男子持台球杆殴打2名女店员被抓校方回应护栏损坏小学生课间坠楼外国人感慨凌晨的中国很安全火箭最近9战8胜1负王树国3次鞠躬告别西交大师生房客欠租失踪 房东直发愁萧美琴窜访捷克 外交部回应山西省委原副书记商黎光被逮捕阿根廷将发行1万与2万面值的纸币英国王室又一合照被质疑P图男子被猫抓伤后确诊“猫抓病”