您的位置:首页 > 其它

Hibernate第四课--HIbernate三大状态转换

2017-07-22 23:31 204 查看
瞬时态(Transient):刚new的一个对象(JVM存在,session缓存中没有,数据库不存在)持久态(Persistent):存储到数据库(JVM存在,session缓存存在,数据库存在)脱管态(Detached):session缓存关闭(JVM存在,session缓存不存在,数据库存在)Session方法:session.save(对象)
@Test
publicvoidtestSave(){
System.out.println("================Savestart===============");
session.getTransaction().begin();
Students=newStudent();
s.setName("zhansan");
session.save(s);
session.getTransaction().commit();
log.debug("Student"+s);
System.out.println("=================Saveend=============");
}
[/code]session.delete(对象)
@Test
publicvoidtestDelete(){
System.out.println("================Deletestart===============");
session.getTransaction().begin();
Students=newStudent();
s.setId(14);
s.setName("zhansan");
session.delete(s);
session.getTransaction().commit();
log.debug("Student"+s);
System.out.println("=================Deleteend=============");
}
[/code]LoadStudents1=(Student)session.load(Student.class,1);//1是查询Student的条件
@Test
publicvoidtestLoad(){
System.out.println("================Loadstart===============");
session.getTransaction().begin();
//第二个参数是一个主键id查询条件
Students=(Student)session.load(Student.class,15);
session.getTransaction().commit();
/*
*get与load区别:
*get直接查询
*load延迟加载:在需要用到时才加载,如果没有用到就先不加载
*/
//log.debug("Student"+s);
System.out.println("=================Loadend=============");
}
[/code]GetStudents1=(Student)session.get(Student.class,1);
@Test
publicvoidtestGet(){
System.out.println("================Getstart===============");
session.getTransaction().begin();
//第二个参数是一个主键id查询条件
Students=(Student)session.get(Student.class,15);
session.getTransaction().commit();
log.debug("Student"+s);
System.out.println("=================Getend=============");
}
[/code]get与load的区别(面试重点,原理)1.不存在对应记录时表现不一样2.load返回的是代理对象,等到真正用到对象的内容时才发出sql语句3.get直接从数据库加载,不会延迟updatessession.update(对象);1.用来更新detached对象,更新完成后转为persistent状态2.更新transient对象会报错3.更新自己设定id的transient对象可以(数据库有对应记录)4.persistent状态的对象只要设定(如:t.setName…)不同字段就会发生更新5.更新部分更改的字段a)xml设定property标签的update属性,annotation设定@Column的updatable属性,不过这种方式很少用,因为不灵活(忘记)b)使用xml中的dynamic-update,JPA1.0Annotation没有对应的属性,hibernate扩展?i.同一个session可以,跨session不行,不过可以用merge()(不重要)c)使用HQL(EjBQL)(建议)
@Test
publicvoidtestUpdate(){
System.out.println("================Updatestart===============");
session.getTransaction().begin();
Students=newStudent();
s.setId(15);
s.setName("lisi");
//第二个参数是一个主键id查询条件
session.update(s);
session.getTransaction().commit();
log.debug("Student"+s);
System.out.println("=================Updateend=============");
}
[/code]session.saveOrUpdate(s);存在时,update,不存在时添加
@Test
publicvoidtestSaveOrUpdate(){
System.out.println("================Updatestart===============");
session.getTransaction().begin();
Students=newStudent();
s.setName("saveorupdate");
//注释下一行变成插入,不注释变成修改
s.setId(15);
//既可以存入也可以修改
session.saveOrUpdate(s);
session.getTransaction().commit();
log.debug("Student"+s);
System.out.println("=================Updateend=============");
}
[/code]clear方法session.clear();1.无论是load还是get,都会首先査找缓存(一级缓存),如果没有,才会去数据库査找,调用clear()方法可以强制清除session缓存flush()方法session.flush();1.当session的事务提交后,会强制将内存(session缓存)与数据库同步.默认情况下是session的事务提交(commit)时才同步!2.session的FlushMode设置,可以设定在什么时候同步缓存与数据库(很少用)例如:session.setFlushMode(FlushMode.AUTO)
@Test
publicvoidtestClear_flush(){
System.out.println("================Clear_flushstart===============");
session.getTransaction().begin();
//既可以存入也可以修改
Students=(Student)session.load(Student.class,15);
session.clear();//如果不注释load缓存中的数据被清除报错
session.flush();//将数据库缓存commit后都刷入数据库
session.getTransaction().commit();
log.debug("Student"+s);
System.out.println("=================Clear_flushend=============");
}
[/code]save和persist的区别save把一个临时实例持久化,因为需要返回一个主键值,因此会立即执行insert语句persist把一个临时实例持久化标识符在事务外部调用时则不会立即执行insert语句,flush时执行,适用与长事务在事务内调用还是会立即执行insert语句的。
@Test
publicvoidtestSave(){
System.out.println("================Savestart===============");
System.out.println("begin");
session.getTransaction().begin();
Students=newStudent();
s.setName("zhansan");
session.save(s);
System.out.println("flushcommit");
session.flush();
session.getTransaction().commit();
log.debug("Student"+s);
System.out.println("=================Saveend=============");
}
@Test
publicvoidtestPesistIn(){
System.out.println("================PesistInstart===============");
Students=newStudent();
s.setName("zhansan");
System.out.println("begin");
session.getTransaction().begin();
session.persist(s);
System.out.println("flushcommit");
session.flush();
session.getTransaction().commit();
log.debug("Student"+s);
System.out.println("=================PesistInend=============");
}
@Test
publicvoidtestPesistOut(){
System.out.println("================PesistOutstart===============");
Students=newStudent();
s.setName("zhansan");
session.persist(s);
System.out.println("begin");
session.getTransaction().begin();
System.out.println("flushcommit");
session.flush();
session.getTransaction().commit();
log.debug("Student"+s);
System.out.println("=================PesistOutend=============");
}
[/code]输出结果:================Savestart===============beginHibernate:insertintoStudent(name)values(?)flushcommit2015-06-3018:03:42,030[com.liuhao.hibernate4.demo.coreapi.test.CoreAPITest]-[DEBUG]Studentcom.liuhao.hibernate4.demo.coreapi.Student@4b82d2[id=26,name=zhansan]=================Saveend=============================PesistInstart===============beginHibernate:insertintoStudent(name)values(?)flushcommit2015-06-3018:04:17,819[com.liuhao.hibernate4.demo.coreapi.test.CoreAPITest]-[DEBUG]Studentcom.liuhao.hibernate4.demo.coreapi.Student@91f005[id=27,name=zhansan]=================PesistInend=============================PesistOutstart===============beginflushcommitHibernate:insertintoStudent(name)values(?)2015-06-3018:04:31,715[com.liuhao.hibernate4.demo.coreapi.test.CoreAPITest]-[DEBUG]Studentcom.liuhao.hibernate4.demo.coreapi.Student@196e136[id=28,name=zhansan]=================PesistOutend=============merge如果session中存在相同持久化标识(identifier)的实例,用用户给出的对象的状态覆盖旧有的持久实例如果session没有相应的持久实例,则尝试从数据库中加载,或创建新的持久化实例,最后返回该持久实例用户给出的这个对象没有被关联到session上,它依旧是脱管的
packagecomliuhao.hibernate4.demo.function.test;
importorg.apache.log4j.Logger;
importorg.hibernate.Session;
importorg.hibernate.SessionFactory;
importorg.junit.After;
importorg.junit.Before;
importorg.junit.Test;
importcom.liuhao.hibernate4.demo.function.Student;
importcom.liuhao.hibernate4.demo.uril.HibernateUtil;
publicclassfunctionTest{
privateLoggerlog=Logger.getLogger(functionTest.class);
privatestaticSessionFactorysfactory;
privatestaticSessionsession;
/**
*@throwsjava.lang.Exception
*@return@void
*/
@Before
publicvoidsetUp()throwsException{
sfactory=HibernateUtil.getSessionFactory();
session=sfactory.openSession();
}
/**
*@throwsjava.lang.Exception
*@return@void
*/
@After
publicvoidtearDown()throwsException{
if(session!=null)
session.close();
if(sfactory!=null)
sfactory.close();
}
/*
*准备:数据库存在id=1的行
*如果session没有merge(a)对象标识的相同的持久化实例,从数据库加载出实例b,实例b的值从a完全拷贝,最后返回持久化实例b
*
*控制台输出:
1.session查询同a标识(主键)相同的对象
2.session没有,从数据库查询a标识的字段
Hibernate:selectstudent0_.idasid1_0_0_,student0_.nameasname2_0_0_from
Studentstudent0_wherestudent0_.id=?
2015-06-3022:30:26,223[comliuhao.hibernate4.demo.function.test.functionTest]-[
DEBUG]Student:Students1[id=1,name=ssssssssssssss]
3.数据库返回的持久化实例b的值完全从a拷贝,然后返回
2015-06-3022:30:26,223[comliuhao.hibernate4.demo.function.test.functionTest]-[
DEBUG]Student:Students2[id=1,name=ssssssssssssss]
*/
@Test
publicvoidtestMerge(){
session.beginTransaction();
Students=newStudent();
s.setId(1);
s.setName("ssssssssssssss");
Students2=(Student)session.merge(s);
log.debug("Students1:"+s);
log.debug("Students2:"+s2);
session.getTransaction().commit();
session.flush();
}
/*
*如果session中存在相同持久化标识(identifier)的实例,a对象覆盖session中持久化实例值
*
*控制台输出:
Hibernate:selectstudent0_.idasid1_0_0_,student0_.nameasname2_0_0_from
Studentstudent0_wherestudent0_.id=?
2015-06-3022:46:56,520[comliuhao.hibernate4.demo.function.test.functionTest]-[
DEBUG]Studentstr2:Student[id=1,name=2222222]
2015-06-3022:46:56,521[comliuhao.hibernate4.demo.function.test.functionTest]-[
DEBUG]Studentstr1:Student[id=1,name=2222222]
*/
@Test
publicvoidtestMerge2(){
Studentstr1=newStudent();
str1.setId(1);
str1.setName("1111111");
session.beginTransaction();
//保证session存在持久化实例
Studentstr2=(Student)session.get(Student.class,1);
str1.setName("2222222");
session.merge(str1);
log.debug("Studentstr2:"+str2);//这里改变了,说明持久态的数据也会改变
str2.setName("3333333");
log.debug("Studentstr1:"+str1);//这里不会改变,说明第一个游离态的数据没有被持久化撒;
session.clear();
}
}
[/code]update与merge区别?当我们使用update的时候,执行完成后,我们提供的对象A的状态变成持久化状态但当我们使用merge的时候,执行完成,我们提供的对象A还是脱管状态,hibernate或者new了一个B,或者检索到一个持久对象B,并把我们提供的对象A的所有的值拷贝到这个B,执行完成后B是持久状态,而我们提供的A还是托管状态evictclear完整的清除session缓存evcit(obj)把某个持久化对象从session的缓存中清空。refreshlock瞬时态(Transient):刚new的一个对象(JVM存在,session缓存中没有,数据库不存在)持久态(Persistent):存储到数据库(JVM存在,session缓存存在,数据库存在)脱管态(Detached):session缓存关闭(JVM存在,session缓存不存在,数据库存在)Session方法:session.save(对象)
@Test
publicvoidtestSave(){
System.out.println("================Savestart===============");
session.getTransaction().begin();
Students=newStudent();
s.setName("zhansan");
session.save(s);
session.getTransaction().commit();
log.debug("Student"+s);
System.out.println("=================Saveend=============");
}
[/code]session.delete(对象)
@Test
publicvoidtestDelete(){
System.out.println("================Deletestart===============");
session.getTransaction().begin();
Students=newStudent();
s.setId(14);
s.setName("zhansan");
session.delete(s);
session.getTransaction().commit();
log.debug("Student"+s);
System.out.println("=================Deleteend=============");
}
[/code]LoadStudents1=(Student)session.load(Student.class,1);//1是查询Student的条件
@Test
publicvoidtestLoad(){
System.out.println("================Loadstart===============");
session.getTransaction().begin();
//第二个参数是一个主键id查询条件
Students=(Student)session.load(Student.class,15);
session.getTransaction().commit();
/*
*get与load区别:
*get直接查询
*load延迟加载:在需要用到时才加载,如果没有用到就先不加载
*/
//log.debug("Student"+s);
System.out.println("=================Loadend=============");
}
[/code]GetStudents1=(Student)session.get(Student.class,1);
@Test
publicvoidtestGet(){
System.out.println("================Getstart===============");
session.getTransaction().begin();
//第二个参数是一个主键id查询条件
Students=(Student)session.get(Student.class,15);
session.getTransaction().commit();
log.debug("Student"+s);
System.out.println("=================Getend=============");
}
[/code]get与load的区别(面试重点,原理)1.不存在对应记录时表现不一样2.load返回的是代理对象,等到真正用到对象的内容时才发出sql语句3.get直接从数据库加载,不会延迟updatessession.update(对象);1.用来更新detached对象,更新完成后转为persistent状态2.更新transient对象会报错3.更新自己设定id的transient对象可以(数据库有对应记录)4.persistent状态的对象只要设定(如:t.setName…)不同字段就会发生更新5.更新部分更改的字段a)xml设定property标签的update属性,annotation设定@Column的updatable属性,不过这种方式很少用,因为不灵活(忘记)b)使用xml中的dynamic-update,JPA1.0Annotation没有对应的属性,hibernate扩展?i.同一个session可以,跨session不行,不过可以用merge()(不重要)c)使用HQL(EjBQL)(建议)
@Test
publicvoidtestUpdate(){
System.out.println("================Updatestart===============");
session.getTransaction().begin();
Students=newStudent();
s.setId(15);
s.setName("lisi");
//第二个参数是一个主键id查询条件
session.update(s);
session.getTransaction().commit();
log.debug("Student"+s);
System.out.println("=================Updateend=============");
}
[/code]session.saveOrUpdate(s);存在时,update,不存在时添加
@Test
publicvoidtestSaveOrUpdate(){
System.out.println("================Updatestart===============");
session.getTransaction().begin();
Students=newStudent();
s.setName("saveorupdate");
//注释下一行变成插入,不注释变成修改
s.setId(15);
//既可以存入也可以修改
session.saveOrUpdate(s);
session.getTransaction().commit();
log.debug("Student"+s);
System.out.println("=================Updateend=============");
}
[/code]clear方法session.clear();1.无论是load还是get,都会首先査找缓存(一级缓存),如果没有,才会去数据库査找,调用clear()方法可以强制清除session缓存flush()方法session.flush();1.当session的事务提交后,会强制将内存(session缓存)与数据库同步.默认情况下是session的事务提交(commit)时才同步!2.session的FlushMode设置,可以设定在什么时候同步缓存与数据库(很少用)例如:session.setFlushMode(FlushMode.AUTO)
@Test
publicvoidtestClear_flush(){
System.out.println("================Clear_flushstart===============");
session.getTransaction().begin();
//既可以存入也可以修改
Students=(Student)session.load(Student.class,15);
session.clear();//如果不注释load缓存中的数据被清除报错
session.flush();//将数据库缓存commit后都刷入数据库
session.getTransaction().commit();
log.debug("Student"+s);
System.out.println("=================Clear_flushend=============");
}
[/code]save和persist的区别save把一个临时实例持久化,因为需要返回一个主键值,因此会立即执行insert语句persist把一个临时实例持久化标识符在事务外部调用时则不会立即执行insert语句,flush时执行,适用与长事务在事务内调用还是会立即执行insert语句的。
@Test
publicvoidtestSave(){
System.out.println("================Savestart===============");
System.out.println("begin");
session.getTransaction().begin();
Students=newStudent();
s.setName("zhansan");
session.save(s);
System.out.println("flushcommit");
session.flush();
session.getTransaction().commit();
log.debug("Student"+s);
System.out.println("=================Saveend=============");
}
@Test
publicvoidtestPesistIn(){
System.out.println("================PesistInstart===============");
Students=newStudent();
s.setName("zhansan");
System.out.println("begin");
session.getTransaction().begin();
session.persist(s);
System.out.println("flushcommit");
session.flush();
session.getTransaction().commit();
log.debug("Student"+s);
System.out.println("=================PesistInend=============");
}
@Test
publicvoidtestPesistOut(){
System.out.println("================PesistOutstart===============");
Students=newStudent();
s.setName("zhansan");
session.persist(s);
System.out.println("begin");
session.getTransaction().begin();
System.out.println("flushcommit");
session.flush();
session.getTransaction().commit();
log.debug("Student"+s);
System.out.println("=================PesistOutend=============");
}
[/code]输出结果:================Savestart===============beginHibernate:insertintoStudent(name)values(?)flushcommit2015-06-3018:03:42,030[com.liuhao.hibernate4.demo.coreapi.test.CoreAPITest]-[DEBUG]Studentcom.liuhao.hibernate4.demo.coreapi.Student@4b82d2[id=26,name=zhansan]=================Saveend=============================PesistInstart===============beginHibernate:insertintoStudent(name)values(?)flushcommit2015-06-3018:04:17,819[com.liuhao.hibernate4.demo.coreapi.test.CoreAPITest]-[DEBUG]Studentcom.liuhao.hibernate4.demo.coreapi.Student@91f005[id=27,name=zhansan]=================PesistInend=============================PesistOutstart===============beginflushcommitHibernate:insertintoStudent(name)values(?)2015-06-3018:04:31,715[com.liuhao.hibernate4.demo.coreapi.test.CoreAPITest]-[DEBUG]Studentcom.liuhao.hibernate4.demo.coreapi.Student@196e136[id=28,name=zhansan]=================PesistOutend=============merge如果session中存在相同持久化标识(identifier)的实例,用用户给出的对象的状态覆盖旧有的持久实例如果session没有相应的持久实例,则尝试从数据库中加载,或创建新的持久化实例,最后返回该持久实例用户给出的这个对象没有被关联到session上,它依旧是脱管的
packagecomliuhao.hibernate4.demo.function.test;
importorg.apache.log4j.Logger;
importorg.hibernate.Session;
importorg.hibernate.SessionFactory;
importorg.junit.After;
importorg.junit.Before;
importorg.junit.Test;
importcom.liuhao.hibernate4.demo.function.Student;
importcom.liuhao.hibernate4.demo.uril.HibernateUtil;
publicclassfunctionTest{
privateLoggerlog=Logger.getLogger(functionTest.class);
privatestaticSessionFactorysfactory;
privatestaticSessionsession;
/**
*@throwsjava.lang.Exception
*@return@void
*/
@Before
publicvoidsetUp()throwsException{
sfactory=HibernateUtil.getSessionFactory();
session=sfactory.openSession();
}
/**
*@throwsjava.lang.Exception
*@return@void
*/
@After
publicvoidtearDown()throwsException{
if(session!=null)
session.close();
if(sfactory!=null)
sfactory.close();
}
/*
*准备:数据库存在id=1的行
*如果session没有merge(a)对象标识的相同的持久化实例,从数据库加载出实例b,实例b的值从a完全拷贝,最后返回持久化实例b
*
*控制台输出:
1.session查询同a标识(主键)相同的对象
2.session没有,从数据库查询a标识的字段
Hibernate:selectstudent0_.idasid1_0_0_,student0_.nameasname2_0_0_from
Studentstudent0_wherestudent0_.id=?
2015-06-3022:30:26,223[comliuhao.hibernate4.demo.function.test.functionTest]-[
DEBUG]Student:Students1[id=1,name=ssssssssssssss]
3.数据库返回的持久化实例b的值完全从a拷贝,然后返回
2015-06-3022:30:26,223[comliuhao.hibernate4.demo.function.test.functionTest]-[
DEBUG]Student:Students2[id=1,name=ssssssssssssss]
*/
@Test
publicvoidtestMerge(){
session.beginTransaction();
Students=newStudent();
s.setId(1);
s.setName("ssssssssssssss");
Students2=(Student)session.merge(s);
log.debug("Students1:"+s);
log.debug("Students2:"+s2);
session.getTransaction().commit();
session.flush();
}
/*
*如果session中存在相同持久化标识(identifier)的实例,a对象覆盖session中持久化实例值
*
*控制台输出:
Hibernate:selectstudent0_.idasid1_0_0_,student0_.nameasname2_0_0_from
Studentstudent0_wherestudent0_.id=?
2015-06-3022:46:56,520[comliuhao.hibernate4.demo.function.test.functionTest]-[
DEBUG]Studentstr2:Student[id=1,name=2222222]
2015-06-3022:46:56,521[comliuhao.hibernate4.demo.function.test.functionTest]-[
DEBUG]Studentstr1:Student[id=1,name=2222222]
*/
@Test
publicvoidtestMerge2(){
Studentstr1=newStudent();
str1.setId(1);
str1.setName("1111111");
session.beginTransaction();
//保证session存在持久化实例
Studentstr2=(Student)session.get(Student.class,1);
str1.setName("2222222");
session.merge(str1);
log.debug("Studentstr2:"+str2);//这里改变了,说明持久态的数据也会改变
str2.setName("3333333");
log.debug("Studentstr1:"+str1);//这里不会改变,说明第一个游离态的数据没有被持久化撒;
session.clear();
}
}
[/code]update与merge区别?当我们使用update的时候,执行完成后,我们提供的对象A的状态变成持久化状态但当我们使用merge的时候,执行完成,我们提供的对象A还是脱管状态,hibernate或者new了一个B,或者检索到一个持久对象B,并把我们提供的对象A的所有的值拷贝到这个B,执行完成后B是持久状态,而我们提供的A还是托管状态evictclear完整的清除session缓存evcit(obj)把某个持久化对象从session的缓存中清空。refreshlock
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: