现在的位置: 首页 > 综合 > 正文

9、领域对象的三种状态

2018年02月05日 ⁄ 综合 ⁄ 共 7747字 ⁄ 字号 评论关闭

在前面有个例子,是关于更新操作的,我们没有调用session的update()方法,结果一样执行了update语句,这是session缓存的原因

域对象在持久化层的三种状态:

- Session的缓存的作用
- Session清理缓存的时间点
- 对象的临时状态、持久化状态和游离状态
- 用Session的update()方法使游离对象转变为持久化对象

1、理解Session的缓存

- 当Session的save()方法持久化一个Customer对象时,Customer对象被加入到Session的缓存中,以后即使应用程序中的引用变量不再引用Customer对象,只要Session的缓存还没有被清空,Customer对象依然处于生命周期中。(即被Session中的一个变量引用,垃圾回收器不回收)

- 当Session的load()方法视图从数据库中加载一个Customer对象时,Session先判断缓存中是否已经存在这个Customer对象,如果存在,就不需要再到数据库中中检索。(hibernate确保缓存和数据库中的数据一致)

session的save()方法返回主键值

如下代码:

tx = session.beginTransaction();
Customer c1 = new Customer("zhangsan",new HashSet());
//Customer对象被持久化,并且加入到Session的缓存中
session.save(c1);
Long id = c1.getId();
//c1变量不再引用Customer对象
c1 = null;
//从session缓存中读取Customer对象,使c2变量引用Customer对象
Customer c2 = (Customer)session.load(Customer.class,id);
tx.commit();
//关闭session,清空缓存
session.close();
//访问Customer对象
System.out.println(c2.getName());
//c2变量不再引用Customer对象,此时Customer对象结束生命周期。
c2 = null;

 

tx = session.beginTransaction();
Customer c1 = (Customer)session.load(Customer.class,new Long(1));
Customer c2 = (Customer)session.load(Customer.class,new Long(1));
System.out.println(c1 == c2);  //true
tx.commit();
session.close();

修改HibernateTest2:

		try
		{
			tx = session.beginTransaction();
			
			Category category1 = new Category("leval1",null,new HashSet());
			Category category2 = new Category("leval2",null,new HashSet());
			Category category3 = new Category("leval2",null,new HashSet());
			Category category4 = new Category("leval3",null,new HashSet());
			Category category5 = new Category("leval3",null,new HashSet());
			Category category6 = new Category("leval3",null,new HashSet());
			Category category7 = new Category("leval3",null,new HashSet());
			
			category2.setParentCategory(category1);
			category3.setParentCategory(category1);
			
			category1.getChildCategory().add(category2);
			category1.getChildCategory().add(category3);
			
			category3.getChildCategory().add(category4);
			category3.getChildCategory().add(category5);
			
			category4.setParentCategory(category3);
			category5.setParentCategory(category3);
			
			category2.getChildCategory().add(category6);
			category2.getChildCategory().add(category7);
			
			category6.setParentCategory(category2);
			category7.setParentCategory(category2);
			
			System.out.println(session.save(category1));
			
//			Category category = (Category)session.get(Category.class, new Long(1));
			
//			System.out.println(category.getChildCategory().iterator().next().getName());
			
//			session.delete(category);
			tx.commit();
			
			
		}

执行结果:

Hibernate: select max(id) from categories
8
Hibernate: insert into categories (name, category_id, id) values (?, ?, ?)
Hibernate: insert into categories (name, category_id, id) values (?, ?, ?)
Hibernate: insert into categories (name, category_id, id) values (?, ?, ?)
Hibernate: insert into categories (name, category_id, id) values (?, ?, ?)
Hibernate: insert into categories (name, category_id, id) values (?, ?, ?)
Hibernate: insert into categories (name, category_id, id) values (?, ?, ?)
Hibernate: insert into categories (name, category_id, id) values (?, ?, ?)

修改,测试load和get方法不同:

try
		{
			tx = session.beginTransaction();
			
//			Category category1 = new Category("leval1",null,new HashSet());
//			Category category2 = new Category("leval2",null,new HashSet());
//			Category category3 = new Category("leval2",null,new HashSet());
//			Category category4 = new Category("leval3",null,new HashSet());
//			Category category5 = new Category("leval3",null,new HashSet());
//			Category category6 = new Category("leval3",null,new HashSet());
//			Category category7 = new Category("leval3",null,new HashSet());
//			
//			category2.setParentCategory(category1);
//			category3.setParentCategory(category1);
//			
//			category1.getChildCategory().add(category2);
//			category1.getChildCategory().add(category3);
//			
//			category3.getChildCategory().add(category4);
//			category3.getChildCategory().add(category5);
//			
//			category4.setParentCategory(category3);
//			category5.setParentCategory(category3);
//			
//			category2.getChildCategory().add(category6);
//			category2.getChildCategory().add(category7);
//			
//			category6.setParentCategory(category2);
//			category7.setParentCategory(category2);
//			
//			System.out.println(session.save(category1));
			
			Category category = (Category)session.load(Category.class, new Long(1));
			Category category_ = (Category)session.load(Category.class, new Long(1));
			
			System.out.println(category == category_);
			
//			System.out.println(category.getChildCategory().iterator().next().getName());
			
//			session.delete(category);
			
			tx.commit();
			
			
		}

执行结果只显示:true

改为:

try
		{
			tx = session.beginTransaction();
			
//			Category category1 = new Category("leval1",null,new HashSet());
//			Category category2 = new Category("leval2",null,new HashSet());
//			Category category3 = new Category("leval2",null,new HashSet());
//			Category category4 = new Category("leval3",null,new HashSet());
//			Category category5 = new Category("leval3",null,new HashSet());
//			Category category6 = new Category("leval3",null,new HashSet());
//			Category category7 = new Category("leval3",null,new HashSet());
//			
//			category2.setParentCategory(category1);
//			category3.setParentCategory(category1);
//			
//			category1.getChildCategory().add(category2);
//			category1.getChildCategory().add(category3);
//			
//			category3.getChildCategory().add(category4);
//			category3.getChildCategory().add(category5);
//			
//			category4.setParentCategory(category3);
//			category5.setParentCategory(category3);
//			
//			category2.getChildCategory().add(category6);
//			category2.getChildCategory().add(category7);
//			
//			category6.setParentCategory(category2);
//			category7.setParentCategory(category2);
//			
//			System.out.println(session.save(category1));
			
			Category category = (Category)session.get(Category.class, new Long(1));
			Category category_ = (Category)session.get(Category.class, new Long(1));
			
			System.out.println(category == category_);
			
//			System.out.println(category.getChildCategory().iterator().next().getName());
			
//			session.delete(category);
			
			tx.commit();
			
			
		}

 

执行结果:

Hibernate: select category0_.id as id2_0_, category0_.name as name2_0_, category0_.category_id as category3_2_0_ from categories category0_ where category0_.id=?
true
执行了查询语句。

修改程序:

try
		{
			tx = session.beginTransaction();
			

			
			Category category = (Category)session.load(Category.class, new Long(1));
			Category category_ = (Category)session.load(Category.class, new Long(1));
			
			
			System.out.println(category.getName());
			System.out.println(category == category_);
			
//			System.out.println(category.getChildCategory().iterator().next().getName());
			
//			session.delete(category);
			
			tx.commit();
			
			
		}

执行结果:

Hibernate: select category0_.id as id2_0_, category0_.name as name2_0_, category0_.category_id as category3_2_0_ from categories category0_ where category0_.id=?
leval1
true
在使用load后又使用了对象,就执行查询语句

修改:

System.out.println(category_.getName());
   System.out.println(category == category_);

再加一个打印category_的语句,结果:

Hibernate: select category0_.id as id2_0_, category0_.name as name2_0_, category0_.category_id as category3_2_0_ from categories category0_ where category0_.id=?
leval1
leval1
true

第一次load的时候category对象存入了缓存,所以第二次打印   System.out.println(category == category_);时直接在混村中取。

2、Session的缓存的作用

(1)减小访问数据库的频率。应用程序从内存中读取持久化对象的速度显然比到数据库中查询数据的速度快多了。因此Session的缓存可以提高数据访问的性能。
(2)保证缓存中的对象与数据库中的相关记录保持同步。当缓存中持久化对象的状态发生了变化,Session并不会立即执行相关的SQL语句,这使得Session能够把几条相关的SQL语句合并为一条SQL语句,以便减少访问数据库的次数,从而提高应用程序的性能。

3、Session清理缓存

清理缓存是指按照缓存中对象的状态的变化来同步更新数据库

4、清理缓存的时间点

session会在下面的时间点清理缓存:
- 当应用程序调用org.hibernate.tranaction的commit()方法的时候,commit()方法先清理缓存,然后在向数据库提交事务。
- 当应用程序显示调用Session的flush()方法的时候

5、Hibernate的二级缓存结构

Session级别的缓存又叫做一级缓存;不能修改不能禁用。由于Session对象的生命周期通常对应一个数据库事务或者一个应用事务,因此它的缓存是事务范围的缓存。第一级缓存是必须的,不允许而且事实上也无法被卸载。在第一级缓存中,持久化类的每个实例都具有唯一的OID。

第二级缓存是一个可插拔的缓存插件,由SessionFactory管理,SessionFactory级别的缓存叫做二级缓存,可以修改。由于SessionFactory对象的生命周期和应用程序的整个进程对应,因此第二级缓存是进程范围的缓存。这个缓存中存放的是对象的散装数据。第二级缓存是可选的,可以在每个类或每个集合的粒度上配置第二级缓存。

hibernate的二级缓存结构:

6、在Hibernate应用中Java对象的状态

- 临时状态(transient):刚刚用new语句创建,还没有被持久化,不处于Session的缓存中。处于临时状态的Java对象被称为临时对象。
- 持久化状态(persistent):已经被持久化,加入到Session的缓存中。处于出计划状态的Java对象被称为持久化对象。
- 游离状态(detached):已经被持久化,但不再处于Session的缓存中。处于游离状态的Java对象被称为游离对象

对象的状态转换图:

Customer对象的状态转换过程:

Session的update()方法完成以下操作:

- 把Customer对象重新加入到Session缓存中,使他变为持久化对象。
- 计划执行一个update语句。值得注意的是,Session只有在清理缓存的时候才会执行update语句,并且在执行时才会把Customer对象当前的属性值组装到update语句中。因此,即使程序中多次修改了Customer对象的属性,在清理缓存时只会执行一次uodate语句。

 

客户层与业务逻辑层之间传递临时对象和游离对象的过程:

 

抱歉!评论已关闭.