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,数据库没有更新



  • 相关阅读:
    测试管理_测试工作量估算
    Mycat原理、应用场景
    linux负载均衡总结性说明(四层负载/七层负载)
    Spring自动装配Bean的五种方式
    计算机组成原理总结
    MyBatis总结
    系统吞吐量(TPS)、用户并发量、性能测试概念和公式
    初探Nginx服务器的整体架构
    mybatis架构理解
    linux环境上运行.net core 初探
  • 原文地址:https://www.cnblogs.com/lanzhi/p/6469538.html
Copyright © 2011-2022 走看看