`
Java_大猫
  • 浏览: 170518 次
  • 性别: Icon_minigender_1
  • 来自: 大连
社区版块
存档分类
最新评论

深入浅出hibernate笔记

阅读更多
深入浅出hibernate笔记
hibernate数据检索
1.Criteria Query
2.HQL


数据加载
1.即时加载
2.延迟加载
3.预先加载
4.批量加载

hibernate持久化
1.自由态,transient,即实体对象在内存中的自由存在,它与数据库中的记录无关。
2.持久态,persistent,即实体对象处于由hibernate框架所管理的状态。这种状态,实体对象的引用被纳入hibernate实体容器中加以管理。
3.游离态,处于persistent状态的对象,其对应的session实例关闭之后,那么,此对象就处于detached状态。


VO与PO
vo:自由态,游离态
po:持久态

实体对象识别
hashcode,equals

脏数据检查
这里的脏数据并非废弃或者无用的数据,而是指一个数据对象所携带的信息发生了改变之后的状态。
1.数据对象监控(对对象的setter方法设置拦截器)
2.数据版本比对(hibernate采用)

unsaved-value
数据保存时,hibernate将根据这个值来判断对象是否需要保存。
首先,hibernate会读取目标对象的id。
之后,将此值与unsaved-value进行比对,如果相等,则目标对象尚未保存,否则无需进行保存操作。

数据缓存
1.事务级缓存-session lever
2.应用级、进程级缓存-sessionfactory lever
3.分布式缓存-jvm之间共享

hibernate(1,内部缓存 2,二级缓存)
内部缓存实现:session在内部维护了一个map数据类型,此数据类型中保持了所有的与当前session相关联的数据对象。如需加载,首先会分

局所要加载的类和id,在entitiesByKey中寻找。同时加载类也会对map进行管理。

二级缓存考虑:
1.数据库是否与其他应用共享
2.应用是否需要部署在集群环境中
第三方缓存实现接口:
JCS
EHCache
OSCache
JBoss Cache
SwarmCache


需要保证数据访问的排他性。
1.悲观锁
对数据被外界修改持保守态度。是基于数据库的锁机制实现。
query.setLockMode("user",LockMode.UPGRADE);//生成的sql后加for update
Criteria.setLockMode
session.lock

LockMode.none    无锁机制
LockMode.WRITE    在insert和update时,自动获取
LockMode.READ    读取的时候,自动获取

2.乐观锁
大多是基于数据版本记录机制实现。避免了长事务中的数据库加锁的开销。
<class
    optimistic-lock="version"
>


数据加载
1.session.get/load
    如果未能发现符合条件的记录,get方法返回null,而load方法会抛出一个objectNotFoundException
    load方法可返回试题的代理类实例,而get方法永远直接返回实体类。
    load方法可以充分利用内部缓存和二级缓存中的现有数据,而get方法则仅仅在内部缓存中进行数据查找,如果没有则直接sql。


find方法执行select sql从数据库中获得所有符合条件的记录并构造相应的实体对象,实体对象构造完毕后,将其纳入缓存。
iterate方法执行时,首先执行一条select sql以获取所有符合查询条件的id,再查询缓存。

hibernate.cache.use_query_cache true


延迟加载
就是在需要数据的时候,才真正执行数据加载操作。
hibernate3同时提供了属性的延迟加载功能。
原理:cglib可以在运行期动态生成java class。真正的对象在代理类.targe中,当调用user.getName方法时,调用代理类的getname方法,会检查target是否存在目标对象,如果不存在则发起查询指令,写回target对象。
集合类型的延迟加载:


session.save    save方法不会把实体对象纳入二级缓存,如果存在级联关系,对此进行递归。
session.update    本身并没有发送update,而是在session.flush(强制数据库同步,在session关闭时自动调用)方法中执行
session.saveorupdate    是save和update方法的组合应用。

数据批量操作
hibernate.jdbc.batch_size 25
1.jdbc
PreparedStatement ps = conn.prepareStatement("insert into TUser(name) values(?);");
for(int k=0;k<400;k++){
    for(int i=0;i<25;i++){
        ps.setString(1,"user");
        ps.addBatch();
    }
    ps.executeBatch();
    conn.commit();
}
2.hibernate
Transaction tx = session.beginTransaction();
for(int i=0;i<10000;i++){
    TUser user = new TUser();
    user.setName("user"+i);
    session.save(user);

    if(i%25==0){
        session.flush();
        session.clear();
    }
}
tx.commit();


hibernate collection
1.set
2.bag:实现了一个允许包含重复元素的 set
3.map

结果集排序
1.sort
<set name="addresses"
    sort="org.sample.LengthComparator"></set>实现了接口java.util.Comparator
2.order by
<set name="addresses"
    order-by="address desc"></set>实现中借助了jdk1.4中的新增集合类linkedHashSet以及LinkedHashMap。

hibernate回调与拦截机制
hibernate通过lifecycle,Validatable接口制定了对象CRUD过程中的回调(CallBack)方式。
Interceptor接口定义了hibernate中的通用拦截机制。

hibernate分页
Criteria criteria = session.createCritera(TUser.class);
criteria.add(Expression.eq("age","20"));
criteria.setFirstResult(100);
criteria.setFetchSize(20);
同样,query接口也提供了一致的方法。抽象类net.sf.hibernate.dialect指定了所有底层数据库的对外统一接口。

session管理
ThreadLocal模式得到了大量使用。
ThreadLocal是java中一种较为特殊的线程绑定机制。通过ThreadLocal存取的数据,总是与当前线程相关,也就是说,jvm为每个运行的线程

,绑定了私有的本地实例存取空间,从而为多线程环境常出现的并发访问问题提供了一种隔离机制。
localSession.set(getSession());//获取session实例并保存
Session session = (Session)localSession.get();//通过get方法取出session
原理:在jvm中维护一个map,这个map的key就是当前的线程对象,而value则是通过ThreadLocal.set方法保存的对象实例。


hibernate优化策略
1.在允许的情况下,选用最新版本的hibernate
2.制定合理的缓存策略
3.采用合理的session管理机制
4.尽量使用延迟加载特性
5.设定合理的批处理参数(batch_size)
6.如果可能,选用uuid作为主键生成器
7.如果可能,选用基于version的乐观锁策略替代悲观锁
8.开发过程中,打开hibernate.show_sql
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics