zoukankan      html  css  js  c++  java
  • Hibernate——(5)持久化对象和一级缓存机制

    一、对象的三种状态

    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、修改数据库表
    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;
    
    3、Foo.hbm.xml
    <?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>
    4、HibernateUtil
    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);
    		}
    	}
    }
    5、TestPeresistence
    a、测试:当foo为持久态时,修改value为foo200
    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();
    	}
    }
    如上所示,当执行了 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,数据库没有更新



  • 相关阅读:
    〖Linux〗Kubuntu设置打开应用时就只在打开时的工作区显示
    〖Linux〗Kubuntu, the application 'Google Chrome' has requested to open the wallet 'kdewallet'解决方法
    unity, dll is not allowed to be included or could not be found
    android check box 自定义图片
    unity, ios skin crash
    unity, Collider2D.bounds的一个坑
    unity, ContentSizeFitter立即生效
    类里的通用成员函数应声明为static
    unity, Gizmos.DrawMesh一个坑
    直线切割凹多边形
  • 原文地址:https://www.cnblogs.com/lanzhi/p/6469538.html
Copyright © 2011-2022 走看看