您的位置:首页 > 其它

Hibernate——(5)持久化对象和一级缓存机制

2014-03-28 16:47 399 查看


一、对象的三种状态

1、暂时态:当对象刚创建,和Session没有发生任何关系时,当程序运行完就即刻消失,被称为暂时态。
2、持久态:当执行如下代码时,对象变为持久态
Emp e = new Emp();
session.save();
持久态的对象和Session发生了关系,如执行了save,get,query等方法
Session中会缓存该对象(Session的缓存叫一级缓存)
Session再获取对象时,首先去查找一级缓存,如果没有才查询数据库
Session要负责将持久态对象的变化更新到数据库。
是在flush()的时候更新,tx在提交的时候会自动调用session的flush()
3、游离态:调用了session.evict(Object obj)方法,和Session解除了关系


二、一级缓存机制

一级缓存机制
其一,如果 session 被查询,session 将先到缓存中查找是否有被查询的对象,找到则直接取出,否则才查询数据库;
其二,session 需要负责实时维护在缓存中的数据,保证缓存中的数据与数据库中数据的一致性,一旦用户对缓存中数据做了修改,session立刻将数据更新到数据库中。


三、案例:对象的3中状态

1、使用前面使用的项目(请参考Hibernate系列的前几篇)
2、修改数据库表



<strong><span style="font-family:FangSong_GB2312;font-size:14px;">DROP TABLE IF EXISTS t_foo;  

CREATE TABLE t_foo (  

t_id int(11) NOT NULL AUTO_INCREMENT,  

t_value varchar(50) NOT NULL,  

PRIMARY KEY (t_id)  

) ENGINE=InnoDB;  

</span></strong>  

3、Foo.hbm.xml



<strong><span style="font-family:FangSong_GB2312;font-size:14px;"><?xml version="1.0" encoding="utf-8"?>  

<!DOCTYPE hibernate-mapping PUBLIC  

"-//Hibernate/Hibernate Mapping DTD 3.0//EN"  

"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">  

<hibernate-mapping package="com.xsyu.tts.po">  

    <class name="Foo" table="t_foo">  

        <id name="id" type="java.lang.Integer" column="t_id">  

            <!-- 用来指明主键的生成方式 -->  

            <generator class="identity"></generator>  

        </id>  

        <property name="value" type="java.lang.String" column="t_value" />  

    </class>  

</hibernate-mapping></span></strong>  

4、HibernateUtil



<strong><span style="font-family:FangSong_GB2312;font-size:14px;">package com.xsyu.tts.util;  

  

import org.hibernate.Session;  

import org.hibernate.SessionFactory;  

import org.hibernate.cfg.Configuration;  

  

public class HibernateUtils {  

    private static ThreadLocal<Session> tl = new ThreadLocal<Session>();  

    private static Configuration conf;  

    private static SessionFactory factory;  

    static {  

        conf = new Configuration();  

        conf.configure();  

        factory = conf.buildSessionFactory();  

    }  

  

    /** 

     *  

     * @return 

     */  

    public static Session getSession() {  

        // factory.getCurrentSession();  

        Session session = tl.get();  

        if (session == null) {  

            session = factory.openSession();  

            tl.set(session);  

        }  

        return session;  

    }  

  

    public static void closeSession() {  

        Session session = tl.get();  

        if (session != null) {  

            session.close();  

            tl.set(null);  

        }  

    }  

}</span></strong>  

5、TestPeresistence
a、测试:当foo为持久态时,修改value为foo200



<strong><span style="font-family:FangSong_GB2312;font-size:14px;">public class TestPersistence {  

    @Test  

    public void testPersistence1() {  

        Foo foo = new Foo();  

        foo.setValue("foo100"); // 1. 现在的foo是暂时态  

        Session session = HibernateUtils.getSession();  

        Transaction tx = session.beginTransaction();  

        session.save(foo);  

        // 2. 现在的foo是持久态  

        // 测试:当foo为持久态时,修改value为foo200  

        foo.setValue("foo200");  

        tx.commit();  

        session.close();  

    }  

}</span></strong>  

如上所示,当执行了 session.save(foo)语句,对象变为持久态,当执行了 foo.setValue("foo200");语句后,session 自劢把该对象更新到数据库中。
b、数据库结果





c、控制台显示





session.save(foo);语句执行后,Hibernate 自动执行了 insert 操作,foo.setValue("foo200");语句执行后,Hibernate 又自动执行了 update 操作。
当事务提交时,session会把持久对象的改变更新到数据。
d、再修改一下





e、控制台
查看控制台,先执行了一次 session.flash(),之后 tx.commit()操作又自动执行了一次 session.flash(),所以,执行了2次update操作。





6、TestPersistence
a、新建testPersistence()方法





如上,凡是被session处理过的对象,都是持久态,
id=1的Foo对象在之前已经被持久化到了数据库中,
所以,通过get方法查询出的foo1和foo2对象时同一个对象。
如果session查询,foo1指向对象是持久态的,该对象将缓存于session中
Foo foo1 = (Foo)session.get(Foo.class, 1);
当session再一次查询
Foo foo2 = (Foo)session.get(Foo.class, 1);
session会首先在一级缓存中查询id=1的foo对象,
如果找到了,就直接从一级缓存中取,如果找不到,才查询数据库。
此时,如果执行









控制台打印




数据库会更改




当数据被缓存到session中,session就要负责维护缓存中的数据,这是Hibernate中的一个重要机制:一级缓存。
一级缓存机制
其一,如果 session 被查询,session 将先到缓存中查找是否有被查询的对象,找到则直接取出,否则才查询数据库;
其二,session 需要负责实时维护在缓存中的数据,保证缓存中的数据不数据库中数据的一致性,一旦用户对缓存中的数据做了修改,session 立刻将数据更新到数据库中。
b、加入session.evict()方法





当对象被清除出session后,即刻变为游离态,此时代码26-27中对象的修改将不起作用,session不会把游离态的对象更新到数据库中。
c、控制台不再打印update,数据库没有更新



内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: