Hibernate 笔记四

来源:互联网 发布:物体识别软件 编辑:程序博客网 时间:2024/05/23 19:19

对象状态

持久化状态

save方法能够将临时状态转化程持久化状态
使用get或者load方法获取的对象肯定是持久化状态
位于session缓存中

oid 不为空位于session缓存中当执行查询时,持久化对象和数据库中的相关记录session在清理缓存时,会根据持久化对象的属性变化,来同步更新数据库中的内容在同一个session实例的缓存中,数据库表中的每条记录只对应唯一的持久化对象。

临时状态

new 对象时为临时状态

在使用代理主键的情况下,oid通常为null,不处于session的缓存中在数据库中没有对应的记录

游离状态(脱管状态)

当调用session.close();session的缓存被清空,缓存中所有对象都会变成游离对象,生命周期结束

session的evict()方法能够从缓存中删除一个持久化对象,从而时该持久化对象变成游离对象,当session的缓存中保存了大量的持久化对象,会消耗很多内存空间,为了提高性能,调用evict方法,从缓存中删除一些对象

oid不为null不处于session缓存中一般有持久化对象转化成游离对象

代码示例

@Testpublic void add() {    // 获取session    Session session = sf.openSession();    Transaction transaction = session.beginTransaction();    // 创建customer对象,并设置内容    // 1 刚刚创建对象---临时状态---    Customer customer = new Customer();    customer.setName("赵六");    // 存储到session中    // 2将对象保存到session中----持久化状态----,    session.save(customer);    // 3 删除 对象  删除状态    session.delete(customer);    // 提交事务    transaction.commit();    session.close();    //4 当session关闭之后,对象变成游离 脱管状态    System.out.print(customer.getId()+"-----");}

对象状态之间转换

  • 持久化对象和游离状态转换

    //持久化状态和游离状态之间转换(了解)Session s = sf.openSession();Transaction tr = s.beginTransaction();Customer c1 = (Customer)s.get(Customer.class, 1);//产生select语句s.evict(c1);//将持久对象转换成游离对象s.update(c1);//将游离对象转换成持久对象Customer c2 = (Customer)s.get(Customer.class, 1);       tr.commit();//先执行s.flush,然后再提交事务s.close();

Session操作数据库的方法总结

  • save()方法:

    将临时对象转换持久对象
  • update()方法:将游离对象转换持久对象

    注意:当 update() 方法关联一个游离对象时, 如果在 Session 的缓存中已经存在相同 OID 的持久化对象, 会抛出异常
  • evict()方法:

    将持久对象转换成游离对象
  • saveOrUpdate()方法:

    存在save方法和update方法的特征
  • get() load()

    都可以根据给定的 OID 从数据库中加载一个持久化对象区别:1:当数据库中不存在与 OID 对应的记录时, load() 方法抛出 ObjectNotFoundException 异常, 而 get() 方法返回 null2:两者采用不同的延迟检索策略

lazy 懒加载介绍

  • 概念介绍

立即检索: 立即加载检索方法指定的对象,对应配置文件中lazy=false

延迟检索: 延迟加载检索方法指定的对象,对应配置文件中lazy=true

测试立即检索和延迟检索的代码,注意只有load()方法进行查询的时候,会产生延迟检索。
模型类设置为final修饰将无法生成代理对象

 get()方法:立即检索,只要调用get方法查询数据库,马上执行sql语句,查询对应的结果 load()方法:会产生延迟检索,调用load()方法的时候,不会马上查询数据库,而是产生一个代理对象, 代理对象中只初始化对象的OID,不会初始化其他的属性值 而是调用其他属性值的时候,例如c.getName(),此时才会组织sql语句,查询数据库,返回对应的结果 load()方法如何立即检索呢? 只需要更改 class name="xxx" table="xxx" lazy="false">  使用load方法可以对性能进行优化,如果只想获取oid的值(比如删除),此时会采用load()方法比get()更适合,因为不需要查询数据库,就可以获取oid
  • load方式访问游离状态的对象

    org.hibernate.LazyInitializationException: could not initialize proxy - no SessionCustomer c = (Customer)s.load(Customer.class, 1);//调用Hibernate.initialize(),将代理对象放置到方法中,此时就会查询数据//库,返回对应的真实对象Hibernate.initialize(c);        System.out.println(c.getName());
  • 检索策略

    • 立即检索

      优点:不管对象处于持久化状态还是游离状态,都方便使用缺点:select 会直接将所有字段都查询出来     关联查询时,可能会查出没必要查询出的对象,浪费内存优先使用场景:应用程序需要立即访问到对象
    • 延迟检索

      优点:可以自行决定查询哪些对象,降低内存消耗缺点:应用程序使用游离状态的对象时,必须保证其已经被初始化优先使用场景:应用程序不需要立即访问到对象的属性,比如只想获取到对象的oid,做删除操作。            一对多或者多对多关联时

管理Session(Session与本地线程绑定):

获取 Session 对象的方法    Session 对象的生命周期与本地线程绑定   thread    Hibernate 委托程序管理 Session 对象的生命周期  managed
  • 在hibernate的配置文件中,设置session与本地线程绑定的代码

    <property name="hibernate.current_session_context_class">thread</property>测试Session与本地线程绑定    public void testSessionThread(){//      Session s1 = sf.openSession();//      Session s2 = sf.openSession();        Session s1 = sf.getCurrentSession();        Session s2 = sf.getCurrentSession();        System.out.println(s1==s2);//false:此时说明2个Session不是一个对象;true:2个Session是一个对象(与本地线程绑定)//      s1.close();  //      s2.close();      }这里:不再调用sessionFactory.openSession().而是调用sessionFactory. getCurrentSession().获取session对象.从当前的线程提取session,* 当前线程如果存在session对象,取出直接使用* 当前线程如果不存在session对象,获取一个新的session对象和当前的线程绑定

Hibernate二级缓存

  • 在通常情况下会将具有以下特征的数据放入到二级缓存中:

    ● 很少被修改的数据。 ● 不是很重要的数据,允许出现偶尔并发的数据。 ● 不会被并发访问的数据。 ● 常量数据。 ● 不会被第三方修改的数据 

而对于具有以下特征的数据则不适合放在二级缓存中:

    ● 经常被修改的数据。     ● 财务数据,绝对不允许出现并发。     ● 与其他应用共享的数据。 

使用二级缓存的前置条件

对于那些查询非常多但插入、删除、更新非常少的应用程序来说,查询缓存可提升性能。但写入多查询少的没有用,总失效。hibernate程序对数据库有独占的写访问权,其他的进程更新了数据库,hibernate是不可能知道的。 你操作数据库必需直接通过hibernate,如果你调用存储过程,或者自己使用jdbc更新数据库,hibernate也是不知道的。 这个限制相当的棘手,有时候hibernate做批量更新、删除很慢,但是你却不能自己写jdbc来优化。 当然可以用SessionFactory提供的移除缓存的方法(上面的二级缓存的管理里面有介绍) http://blog.csdn.net/runming56/article/details/8574047[[ssh框架相关jar包和api,json,jquery,ajax]](http://pan.baidu.com/s/1nvG7CKT)
原创粉丝点击