当前位置: 首页 > news >正文

Hibernate -- 操作持久化对象

知识点2: session概述

Session 接口是 Hibernate 向应用程序提供的操纵对数据库的最主要的接口,它提供了基本的保存,更新, 删除和加载Java对象的方法.

知识点3:理解session的缓存

Session 接口的实现中包含一系列的 Java 集合 , 这些 Java 集合构成了 Session 缓存 . 只要 Session 实例没有结束生命周期 , 存放在它缓存中的对象也不会结束生命周期
session save() 方法持久化一个对象时,该对象被载入缓存,以后即使程序中不再引用该对象,只要缓存不清空,该对象仍然处于生命周期中。当试图 load() 对象时,会判断缓存中是否存在该对象,有则返回。没有在查询数据库

知识点4:清理session的缓存

Session 具有一个缓存 , 位于缓存中的对象称为持久化对象 , 它和数据库中的相关记录对应 . Session 能够在某些时间点 , 按照缓存中对象的变化来执行相关的 SQL 语句 , 来同步更新数据库 , 这一过程被称为清理缓存 (flush)
默认情况下 Session 在以下时间点清理缓存:
当应用程序调用 Transaction commit () 方法的时 , 该方法先清理缓存 (session.flush()) ,然后在向数据库提交事务 (tx.commit())
当应用程序执行一些查询操作时,如果缓存中持久化对象的属性已经发生了变化,会先清理缓存,以保证查询结果能够反映持久化对象的最新状态
显式调用 Session flush() 方法 .
区别:

     flush:进行清理缓存(此时缓存中的数据并不丢失)的操作,让缓存和数据库同步执行一些列sql语句,但不提交事务,

     commit:先调用flush()方法,然后提交事务.则意味着提交事务意味着对数据库操作永久保存下来。

     reresh:刷新,session和数据库同步,执行查询,把数据库的最新信息显示出来,更新本地缓存的对象状态.

     clear:清空缓存,等价于list.removeAll();

知识点5:在hibernate中java对象的状态

Hibernate 把对象分为 4 种状态持久化状态临时状态游离状态删除状态.

Session 的特定方法能使对象从一个状态转换到另一个状态

 

 

知识点15: 操纵持久化对象-get()  load()

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

 

示例代码:

javabean 及 配置文件参考上篇blog的 Customer.java Order.java Customer.hbm.xml hibernate.cfg.xml Order.hbm.xml

知识点示例代码:

AppFlushClearRefreshCommit.java

package cn.itcast.state;

import java.util.Iterator;
import java.util.Set;

import org.hibernate.FlushMode;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.junit.Test;

public class AppFlushClearRefreshCommit {
	private static  SessionFactory sf=null;
	
	static{
		   Configuration config=new Configuration();
	       config.configure("cn/itcast/state/hibernate.cfg.xml");
	       config.addClass(Customer.class);
	       config.addClass(Order.class);
	       sf=config.buildSessionFactory();
	}
		
	    /*
	     * 知识点4_1:清理session的缓存  测试flush方法的使用
	     */
		@Test
		public  void testFlush(){
			   Session session=sf.openSession();
			   Transaction tx=session.beginTransaction();
			   
			   Customer c=new Customer();
			   c.setName("曹操");
			   
			   session.save(c);
			   
			   /*
			    * 清理缓存,刷新session的一级缓存中数据到数据库中,让缓存中的数据跟数据库同步 方向缓存--->数据库
			    *         缓存中的数据不丢失
			    */
			   
			   session.flush();  //会产生insert语句,此时已经在数据库中,但数据库还没有确认
			 
			   tx.commit();  //数据库确认插入的数据
			   session.close();
		}
		
		/*
		 * 知识点4_2:清理session的缓存  测试flush和clear方法的使用
		 */
		@Test
		public  void testFlushClear(){
			   Session session=sf.openSession();
			   Transaction tx=session.beginTransaction();
			   
			   //从数据库查询出的客户放置到session的一级缓存中
			   Customer c4=(Customer)session.get(Customer.class, 4); //select
			   
			   //清理缓存,缓存中的数据不丢失
			   session.flush();
			   //从session的一级缓存中获取要查询的数据
			   Customer c5=(Customer)session.get(Customer.class, 4);  //不会产生select语句
			   
			   //清空缓存,session的一级缓存中的数据丢失
			   session.clear();
			   
			   //缓存中已经没有数据了,需要重新查询数据库
			   Customer c6=(Customer)session.get(Customer.class, 4);  //会产生select语句
			   
			   tx.commit();  //数据库确认插入的数据
			   session.close();
		}
		
		/*
		 * 知识点4_4:清理session缓存    测试refresh方法的使用
		 */
		@Test
		public  void tesRefresh(){
			   Session session=sf.openSession();
			   Transaction tx=session.beginTransaction();
			   
			   Customer c4=(Customer)session.get(Customer.class, 4); //select
			   c4.setName("马超");
			   
			   //刷新数据库中的数据和缓存中的同步,方法向从数据库----> 缓存,产生select语句
			   session.refresh(c4);
			   
			   tx.commit();  //数据库确认插入的数据
			   session.close();
		}
				
	   /*
	    * 知识点4_5:清理session的缓存(设置缓存的清理模式)
	    */
		@Test
		public  void testCacheMode11(){
			   Session session=sf.openSession();
			   Transaction tx=session.beginTransaction();
			   
			   //设置缓存的模式是自动模式
			   Customer c=new Customer();
			   c.setName("秦琼");
			   
			   session.save(c);
			   
			   tx.commit();  //产生insert语句
			   
			   session.close();
		}
		
		   /*
		    * 知识点4_5:清理session的缓存(设置缓存的清理模式)
		    */
			@Test
			public  void testCacheMode12(){
				   Session session=sf.openSession();
				   Transaction tx=session.beginTransaction();
				   
				   //设置缓存的模式是自动模式
				   Customer c=new Customer();
				   c.setName("秦琼");
				   session.save(c);
				   
				   session.flush();//产生insert语句
				   tx.commit();  
				   
				   session.close();
			}
			
			
		 /*
		    * 知识点4_5:清理session的缓存(设置缓存的清理模式)
		    */
			@Test
			public  void testCacheMode13(){
				   Session session=sf.openSession();
				   Transaction tx=session.beginTransaction();
				   
				   //设置缓存的模式是从不清理缓存
				   session.setFlushMode(FlushMode.NEVER);
				   
				   Customer c=new Customer();
				   c.setName("秦琼");
				   session.save(c);
				   
				   //该方法不清理缓存,不会产生insert语句,此时数据不能插入到数据库中
				   tx.commit();  
				   
				   session.close();
			}
			
			
			 /*
			    * 知识点4_5:清理session的缓存(设置缓存的清理模式)
			    */
				@Test
				public  void testCacheMode14(){
					   Session session=sf.openSession();
					   Transaction tx=session.beginTransaction();
					   
					   //设置缓存的模式是从不清理缓存
					   session.setFlushMode(FlushMode.NEVER);
					   
					   Customer c=new Customer();
					   c.setName("秦琼");
					   session.save(c);
					  
					   //该方法清理缓存
					   session.flush(); //产生insert语句
					   
					   //该方法不清理缓存
					   tx.commit();  
					   
					   session.close();
				}
				
				
			   /*
			    * 知识点4_5:清理session的缓存(设置缓存的清理模式)
			    */
				@Test
				public  void testBatchData(){
					   Session session=sf.openSession();
					   Transaction tx=session.beginTransaction();
					   
					   //设置缓存的模式是从不清理缓存
					   session.setFlushMode(FlushMode.NEVER);
					   
					   for(int i=0;i<100000;i++){
						   Customer c=new Customer();
						   c.setName("朱仝"+i);
						   session.save(c);
						   if(i%1000==0){
							   //清理缓存,数据已经存在数据库,就是没有确认
							   session.flush();
							   //清空缓存
							   session.clear();
						   }
					   }
					   
					   //清理缓存
					   session.flush();
					   
					   //该方法不清理缓存
					   tx.commit();  
					   
					   session.close();
				}
					
}

AppState.java

package cn.itcast.state;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.junit.Test;

public class AppState {
	private static SessionFactory sf = null;

	static {
		Configuration config = new Configuration();
		config.configure("cn/itcast/state/hibernate.cfg.xml");
		config.addClass(Customer.class);
		config.addClass(Order.class);
		sf = config.buildSessionFactory();
	}

	/*
	 * 知识点5:临时对象(transient)  对象的状态
	 */
	@Test
	public void teststate() {
		Session session = sf.openSession();
		Transaction tx = session.beginTransaction();
		
		//刚刚创建一个对象,此时就是临时对象,OID=null
		Customer c = new Customer();
		c.setName("曹操");
		System.out.println("c.getId()  "+c.getId()); //null
		
		//此时customer对象变为持久对象(持久对象有OID,OID不为空)处于session的缓存中
		session.save(c);
		System.out.println("c.getId()  "+c.getId());  //存在值

		tx.commit(); // 数据库确认插入的数据
		session.close();  //此时没有一级缓存了
		
		//session关闭后,此时c引用的对象转化为游离对象  不再处于 Session 的缓存中
		System.out.println(c.getId()+"   "+c.getName());
		
		//此时对象不再被引用,被jvm回收
		c=null;
		
/****************************************************************************************************************/		
		session = sf.openSession();
	    tx = session.beginTransaction();
	    
	    //c1在session的一级缓存中存在 是持久对象 
		Customer c1=(Customer)session.get(Customer.class, 5);
	    
		//删除c1对象
		session.delete(c1);
		//此时c1变为删除对象
	    
		tx.commit(); // 数据库确认插入的数据
		session.close();  //此时没有一级缓存了
		
		//session关闭后,此时c1为游离对象
		
/****************************************************************************************************************/
	}
	
	
	
	/*
	 * 知识点5:临时对象(transient)  对象的状态
	 *   * evict()方法:该方法能将持久对象转化为游离对象
	 */
	@Test
	public void testEvict() {
		Session session = sf.openSession();
		Transaction tx = session.beginTransaction();
	
		//c1在session的一级缓存中存在 是持久对象 
		Customer c1=(Customer)session.get(Customer.class, 5);  //产生select语句
		
		//直接从session的一级缓存中查询数据
		Customer c2=(Customer)session.get(Customer.class, 5);   //不产生select语句
	    
		//将session一级缓存中的对象转化为游离对象,此时该对象在session的一级缓存中不存在
	    session.evict(c1);
	    
	   
	    //该方法能将游离对象再转化为持久对象,此时该对象有存在session的一级缓存中
	    session.update(c1);
	    
	    //在缓存中不存在该对象,所以要查询数据库
		Customer c3=(Customer)session.get(Customer.class, 5);  //不产生select语句
		
	    
		tx.commit(); // 数据库确认插入的数据
		session.close();  //此时没有一级缓存了		
	}
}

AppMethod.java

package cn.itcast.state;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.junit.Test;

public class AppMethod {
	
	private static SessionFactory sf = null;

	static {
		Configuration config = new Configuration();
		config.configure("cn/itcast/state/hibernate.cfg.xml");
		config.addClass(Customer.class);
		config.addClass(Order.class);
		sf = config.buildSessionFactory();
	}

	/*
	 * 知识点12: 操纵持久化对象-save()
	 */
	@Test
	public void testSave() {
		Session session = sf.openSession();
		Transaction tx = session.beginTransaction();
	    
		Customer c=new Customer();
	    c.setId(3);  //没有用途
		c.setName("西门庆");
	    session.save(c);
	    
		tx.commit();
		session.close();
	}
	
	/*
	 * 知识点13_1: 操纵持久化对象-update()
	 */
	@Test
	public void updagePersission() {
		Session session = sf.openSession();
		Transaction tx = session.beginTransaction();
	    
		//持久对象
		Customer c=(Customer)session.get(Customer.class, 7);
		
		//游离对象
		session.evict(c);
		
		//游离对象---->持久对象  ---执行update语句
		session.update(c);
		
		tx.commit();
		session.close();
	}
	
    /*
	 * 知识点13_2: 操纵持久化对象-update()
	 *  * 在customer.hbm.xml文件的class标签中增加 select-before-update="true"(在执行更新之前查询)
	 *      * 目的:把要更新的信息又防止到session的一级缓存中,快照有一份
	 *      * 在更新时,哪缓存中的数据和快照比对,没有变化,不再产生update语句
	 */
	
	@Test
	public void updagePersissionClass() {
		Session session = sf.openSession(); 
		Transaction tx = session.beginTransaction();
	    
		//持久对象
		Customer c=(Customer)session.get(Customer.class, 7);
		
		//游离对象
		session.evict(c);
		
		//游离对象---->持久对象  ---执行update语句
		session.update(c);
		
	    
		tx.commit();
		session.close();
	}
	
	/*
	 * 知识点13_3: 操纵持久化对象-update()
	 */
	@Test
	public void updagePersissionOId() {
		Session session = sf.openSession(); 
		Transaction tx = session.beginTransaction();
	    
		//查询数据库  c1持久对象
		Customer c1=(Customer)session.get(Customer.class, 7);
		
		//c1游离对象
		session.evict(c1);
		
		//查询数据库  c2持久对象
		Customer c2=(Customer)session.get(Customer.class, 7);
		
		//c1持久对象
		session.update(c1);
	    
		tx.commit();
		session.close();
	}
	
	/*
	 * 知识点13_4: 操纵持久化对象-update()
	 */
	@Test
	public void updagePersissionWithNoData() {
		Session session = sf.openSession(); 
		Transaction tx = session.beginTransaction();
	    
		//查询数据库  c1持久对象
		Customer c1=(Customer)session.get(Customer.class, 7);
		
		//c1游离对象
		session.evict(c1);
        
		System.out.println("cccccccccccccccc");
		//手动删除数据
		
		//c1持久对象
		session.update(c1);
	    
		tx.commit();
		session.close();
	}
	
	
	/*
	 * 知识点14_2: 操纵持久化对象-saveOrupdate()
	 */
	@Test
	public void SaveOrUpdateTransient() {
		Session session = sf.openSession();
		Transaction tx = session.beginTransaction();
	    
		//临时对象
		Customer c=new Customer();
		c.setName("西门庆");

		session.saveOrUpdate(c);
	    
		tx.commit();
		session.close();
	}
	
	
	/*
	 * 知识点14_3: 操纵持久化对象-saveOrupdate()
	 *            如果是游离对象就用update方法
	 */
	@Test
	public void updagePersissionDetached() {
		Session session = sf.openSession(); 
		Transaction tx = session.beginTransaction();
	    
		//查询数据库  c1持久对象
		Customer c1=(Customer)session.get(Customer.class, 6);
		
		//c1游离对象
		session.evict(c1);
       
		//c1持久对象  执行update方法
		session.saveOrUpdate(c1);
	    
		tx.commit();
		session.close();
	}
	
	/*
	 * 知识点14_4: 操纵持久化对象-saveOrupdate()
	 */
	@Test
	public void updagePersissionPersiss() {
		Session session = sf.openSession(); 
		Transaction tx = session.beginTransaction();
	    
		//查询数据库  c1持久对象
		Customer c1=(Customer)session.get(Customer.class, 6);
		
		//c1持久对象  不会产生update语句
		session.saveOrUpdate(c1);
	    
		tx.commit();
		session.close();
	}
	
	/*
	 * 知识点14_5: 操纵持久化对象-saveOrupdate()
	 *    saveOrUpdate(c)中判定对象为临时对象的标准
	 *      * 如果Id为Integer类型(private Integer id)
	 *         * 如果Id==null执行save操作
	 *         * 如果Id!=null执行update操作
	 *     *  如果javaBean中id为int类型(private int id;)此时id的默认值为0
	 *        在Customer.hbm.xml文件 配置<id name="id" type="integer" unsaved-value="0">增加unsaved-value="0"
	 *          * 如果javaBean中id属性的值与unsaved-value="0"相同,执行insert操作
	 *          * 如果javaBean中id属性的值与unsaved-value="0"不相同,执行update操作
     
	 */
	@Test
	public void SaveOrUpdateUnsaved() {
		Session session = sf.openSession();
		Transaction tx = session.beginTransaction();
	    
		//临时对象
		Customer c=new Customer();
	    
		c.setName("西门庆");

		session.saveOrUpdate(c);
		System.out.println("c.getId()  "+c.getId());
	    
		tx.commit();
		session.close();
	}
	
	/*
	 * 知识点15: 操纵持久化对象-get()  load()
	 *   * 区别
	 *      * 相同点:都是通过id查询对象
	 *      * 不同点;
	 *           * 如果id在数据库中不存在get返回null,load抛出异常
	 *           * get方法总是立即加载,load可以配置延迟和立即两种(后面讲)
	 * 
	 */
	@Test
	public void getOrLoad() {
		Session session = sf.openSession(); 
		Transaction tx = session.beginTransaction();
	    
		Customer c1=(Customer)session.load(Customer.class, 14);
	    System.out.println("c1  = "+c1);	
	
		tx.commit();
		session.close();
	}	
}



 

 

 

 

转载于:https://www.cnblogs.com/xj626852095/p/3648003.html

相关文章:

  • POI 导入导出时异常[java.io.IOException: Broken pipe]
  • linux安全基本防护
  • 网络安全与主机基本防护-linux鸟哥的私房菜服务器篇07(阅读笔记)
  • Andrew Ng经典机器学习课程的Python实现(第1部分)
  • TCP/IP 笔记三
  • R中绘制聚类的离散图
  • 持续集成与持续部署宝典Part 2:创建持续集成流水线
  • 如何在电脑上测试手机网站(补充)和phonegap
  • Qt之在QGraphicsView中绘图
  • 与众不同 windows phone (28) - Feature(特性)之手机方向, 本地化, 应用程序的试用体验, 系统主题资源, 本地数据的加密解密...
  • springBoot 整合 Hazelcast 作为缓存中间件
  • 初识python:格式化输出
  • 算法起步之Kruskal算法
  • 回文自动机学习笔记
  • 深入理解Java类加载器(ClassLoader)
  • php的引用
  • 【译】理解JavaScript:new 关键字
  • 【跃迁之路】【699天】程序员高效学习方法论探索系列(实验阶段456-2019.1.19)...
  • iOS | NSProxy
  • JavaScript学习总结——原型
  • jquery cookie
  • Linux学习笔记6-使用fdisk进行磁盘管理
  • Python 使用 Tornado 框架实现 WebHook 自动部署 Git 项目
  • Python_OOP
  • Redis在Web项目中的应用与实践
  • tab.js分享及浏览器兼容性问题汇总
  • VirtualBox 安装过程中出现 Running VMs found 错误的解决过程
  • 复杂数据处理
  • 机器学习中为什么要做归一化normalization
  • 将回调地狱按在地上摩擦的Promise
  • 精益 React 学习指南 (Lean React)- 1.5 React 与 DOM
  • 警报:线上事故之CountDownLatch的威力
  • 看图轻松理解数据结构与算法系列(基于数组的栈)
  • 网页视频流m3u8/ts视频下载
  • 微信公众号开发小记——5.python微信红包
  • 小程序开发中的那些坑
  • 好程序员大数据教程Hadoop全分布安装(非HA)
  • ​软考-高级-系统架构设计师教程(清华第2版)【第9章 软件可靠性基础知识(P320~344)-思维导图】​
  • ​业务双活的数据切换思路设计(下)
  • !!Dom4j 学习笔记
  • #define
  • (11)工业界推荐系统-小红书推荐场景及内部实践【粗排三塔模型】
  • (20)目标检测算法之YOLOv5计算预选框、详解anchor计算
  • (2009.11版)《网络管理员考试 考前冲刺预测卷及考点解析》复习重点
  • (3)llvm ir转换过程
  • (八)Flask之app.route装饰器函数的参数
  • (附源码)springboot“微印象”在线打印预约系统 毕业设计 061642
  • (附源码)计算机毕业设计大学生兼职系统
  • (欧拉)openEuler系统添加网卡文件配置流程、(欧拉)openEuler系统手动配置ipv6地址流程、(欧拉)openEuler系统网络管理说明
  • (七)MySQL是如何将LRU链表的使用性能优化到极致的?
  • (五)网络优化与超参数选择--九五小庞
  • (转)LINQ之路
  • (转)Windows2003安全设置/维护
  • .NET 8 中引入新的 IHostedLifecycleService 接口 实现定时任务
  • .NET Framework杂记