Hibernate的一些知识点

今天寝室的同学在配Hibernate,我也顺便复习一下了。虽然Hibernate的东西我没有用过,但Hibernate的概念实习的时候看过。

先看一下session.save(obj):

1 在当前session所对应的实体容器(Entity Map)中查询是否存在obj对象的引用
2 如果引用存在,则直接返回obj对象id,save过程结束.
Hibernate中,针对每个Session有一个实体容器(实际上是一个Map对象),
如果此容器中已经保存了目标对象的引用,那么hibernate会认为此对象已经
与Session相关联。
对于save操作而言,如果对象已经与Session相关联(即已经被加入Session
的实体容器中),则无需进行具体的操作。因为之后的Session.flush过程中,
Hibernate会对此实体容器中的对象进行遍历,查找出发生变化的实体,生成
并执行相应的update语句
3 如果引用不存在,则根据映射关系,执行insert操作
a) 将obj对象的引用纳入Hibernate的实体容器
b) save过程结束,返回对象id
而Session.load方法中,再返回对象之前,Hibernate就已经将此对象纳入其实体容器中

VO和PO的主要区别在于:
VO是独立的Java Object
PO是由Hibernate纳入其实体容器(Entity Map)的对象,它代表了与数
据库中某条记录对应的Hibernate实体,PO的变化在事务提交时将反应到实
际数据库中

悲观锁机制:由数据库本身决定

乐观锁机制往往基于系统中的数据存储逻辑,因此也具备一定的局
限性,由于乐观锁机制是在我们的系统中实现,来自外部系统的用户
余额更新操作不受我们系统的控制,因此可能会造成脏数据被更新到数据库中。在
系统设计阶段,我们应该充分考虑到这些情况出现的可能性,并进行相应调整(如
将乐观锁策略在数据库存储过程中实现,对外只开放基于此存储过程的数据更新途
径,而不是将数据库表直接对外公开)

Cache管理:

如果能把数据在本地内存中保留一个镜像,下次访问时只需从内存中直接获取,
那么显然可以带来显著的性能提升引入Cache机制的难点是如何保证内存中数据的有效性,否则脏数据的出现将给系统带来难以预知的严重后果

需要注意的是:Hibernate做为一个应用级的数据访问层封装,只能在其作用范围内
保持Cache中数据的的有效性,也就是说,在我们的系统与第三方系统共享数据库的情况
下,Hibernate的Cache机制可能失效

Hibernate 在本地JVM 中维护了一个缓冲池,并将从数据库获得的数据保存到池中
以供下次重复使用(如果在Hibernate中数据发生了变动,Hibernate同样也会更新池
中的数据版本)
此时,如果有第三方系统对数据库进行了更改,那么,Hibernate并不知道数据库中
的数据已经发生了变化,也就是说,池中的数据还是修改之前的版本,下次读取时,
Hibernate会将此数据返回给上层代码,从而导致潜在的问题(在同一套系统中,基于Hibernate和基于JDBC的两种数据访问方式并存,那么通过JDBC更新数据库的时候,Hibernate同样无法获知数据更新的情况,从而导致脏数据的出现)

Hibernate中的Cache大致分为两层,第一层Cache在Session实现,属于事务
级数据缓冲,一旦事务结束,这个Cache 也就失效。此层Cache 为内置实现,无需我们进行干涉。
第二层Cache,是Hibernate 中对其实例范围内的数据进行缓存的管理容器

Session管理:

在各种Session 管理方案中, ThreadLocal 模式得到了大量使用。ThreadLocal 是
Java中一种较为特殊的线程绑定机制。通过ThreadLocal存取的数据,总是与当前线程相关,
也就是说,JVM 为每个运行的线程,绑定了私有的本地实例存取空间,从而为多线程环境常出
现的并发访问问题提供了一种隔离机制

SessionFactory负责创建Session,SessionFactory是线程安全的,多个并发线程可以同时访问一个SessionFactory 并从中获取Session 实例。而Session并非线程安全,也就是说,如果多个线程同时使用一个Session实例进行数据存取,则将会导致Session 数据存取逻辑混乱

ThreadLocal的独特之处,它会为每个线程维护一个私有的变量空间。实际上,
其实现原理是在JVM 中维护一个Map,这个Map的key 就是当前的线程对象,而value则是
线程通过ThreadLocal.set方法保存的对象实例。当线程调用ThreadLocal.get方法时,
ThreadLocal会根据当前线程对象的引用,取出Map中对应的对象返回

public class HibernateUtil {
private static SessionFactory sessionFactory;
static {
try {
// Create the SessionFactory
sessionFactory = new Configuration().configure().buildSessionFactory();
} catch (HibernateException ex) {
throw new RuntimeException("Configuration problem: " + ex.getMessage(),ex);
}
}
public static final ThreadLocal session = new ThreadLocal();
public static Session currentSession() throws HibernateException
{
Session s = (Session) session.get();
// Open a new Session, if this Thread has none yet
if (s == null) {
s = sessionFactory.openSession();
session.set(s);
}
return s;
}
public static void closeSession() throws HibernateException {
Session s = (Session) session.get();
session.set(null);
if (s != null)
s.close();
}
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值