10. Session flush操作

三个重要存储位置:

       *session ActionQueue insert/update/delete

         主要存放session操作(saveupdatedelete)之后,但尚未发出sql语句的对象的相关信息,简称 临时队列,调用session.flush()操作,会清空队列里的信息,发出sql语句,并改变缓存对象的 existsInDatabase属性值

       *session PersistentContext

          hibernatesession级缓存,其中对象的existsInDatebase属性标志着该缓存对象在数据库中是否存在

       *数据库

session flush方法主要做了两件事:

       * 清理临时队列

       * 发出sql,并修改PersistentContext中对象的existsInDateBase值为true

      

session在什么情况下执行flush

       * 默认在事务提交时

       * 显示的调用flush

       * 在执行查询前,如:iterate

      

调用flush操作后,hibernate按照save(insert),updatedelete顺序发出sql语句,而会按照程序中操作的先后顺序,见后面的测试用例      

1.定义User1(UUID)

package com.bjsxt.hibernate;

 

import java.util.Date;

 

public class User1 {

      

       private String id;    

       private String name;      

       private String password;      

       private Date createTime;      

       private Date expireTime;

 

       public String getId() {

              return id;

       }

       public void setId(String id) {

              this.id = id;

       }

       public String getName() {

              return name;

       }

       public void setName(String name) {

              this.name = name;

       }

       public String getPassword() {

              return password;

       }

       public void setPassword(String password) {

              this.password = password;

       }

       public Date getCreateTime() {

              return createTime;

       }

       public void setCreateTime(Date createTime) {

              this.createTime = createTime;

       }

       public Date getExpireTime() {

              return expireTime;

       }

       public void setExpireTime(Date expireTime) {

              this.expireTime = expireTime;

       }

}

2.定义User1.hbm.xml文件

<?xml version="1.0"?>

<!DOCTYPE hibernate-mapping PUBLIC

       "-//Hibernate/Hibernate Mapping DTD 3.0//EN"

       "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping package="com.bjsxt.hibernate">

       <class name="User1" table="t_user1">

              <id name="id" column="user_id" length="32">

                     <generator class="uuid"/>

              </id>

              <property name="name" unique="true" not-null="true" length="20"/>

              <property name="password" not-null="true" length="10"/>

              <property name="createTime" column="create_time"/>

              <property name="expireTime" column="expire_time"/>

       </class>

</hibernate-mapping>

3.定义User2类(native

package com.bjsxt.hibernate;

 

import java.util.Date;

 

public class User2 {

      

       private int id;

       private String name;

       private String password;

       private Date createTime;      

       private Date expireTime;

 

       public String getName() {

              return name;

       }

       public void setName(String name) {

              this.name = name;

       }

       public String getPassword() {

              return password;

       }

       public void setPassword(String password) {

              this.password = password;

       }

       public Date getCreateTime() {

              return createTime;

       }

       public void setCreateTime(Date createTime) {

              this.createTime = createTime;

       }

       public Date getExpireTime() {

              return expireTime;

       }

       public void setExpireTime(Date expireTime) {

              this.expireTime = expireTime;

       }

       public int getId() {

              return id;

       }

       public void setId(int id) {

              this.id = id;

       }

}

4.定义User2.hbm.xml文件

<?xml version="1.0"?>

<!DOCTYPE hibernate-mapping PUBLIC

       "-//Hibernate/Hibernate Mapping DTD 3.0//EN"

       "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping package="com.bjsxt.hibernate">

       <class name="User2" table="t_user2">

              <id name="id" column="user_id">

                     <generator class="native"/>

              </id>

              <property name="name" unique="true" not-null="true" length="20"/>

              <property name="password" not-null="true" length="10"/>

              <property name="createTime" column="createtime"/>

              <property name="expireTime" column="expiretime"/>

       </class>

</hibernate-mapping>

5.定义User3(assigned)

package com.bjsxt.hibernate;

 

import java.util.Date;

 

public class User3 {

      

       private String id;    

       private String name;      

       private String password;      

       private Date createTime;      

       private Date expireTime;

 

       public String getId() {

              return id;

       }

       public void setId(String id) {

              this.id = id;

       }

       public String getName() {

              return name;

       }

       public void setName(String name) {

              this.name = name;

       }

       public String getPassword() {

              return password;

       }

       public void setPassword(String password) {

              this.password = password;

       }

       public Date getCreateTime() {

              return createTime;

       }

       public void setCreateTime(Date createTime) {

              this.createTime = createTime;

       }

       public Date getExpireTime() {

              return expireTime;

       }

       public void setExpireTime(Date expireTime) {

              this.expireTime = expireTime;

       }

}

6.定义User3.hbm.xml文件

<?xml version="1.0"?>

<!DOCTYPE hibernate-mapping PUBLIC

       "-//Hibernate/Hibernate Mapping DTD 3.0//EN"

       "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping package="com.bjsxt.hibernate">

       <class name="User3" table="t_user3">

              <id name="id" column="user_id" length="32">

                     <generator class="assigned"/>

              </id>

              <property name="name"/>

              <property name="password"/>

              <property name="createTime" column="create_time"/>

              <property name="expireTime" column="expire_time"/>

       </class>

</hibernate-mapping>

6. 定义ExportDB类和HibernateUtils工具类()

7. 编写测试用例

package com.bjsxt.hibernate;

 

import java.util.Date;

import org.hibernate.Session;

import org.hibernate.Transaction;

import junit.framework.TestCase;

 

public class SessionFlushTest extends TestCase {

      

       /**

        * 测试uuid主键生成策略

        */

       public void testSave1() {

              Session session = null;

              Transaction tx = null;

              try {

                     session = HibernateUtils.getSession();

                     tx = session.beginTransaction();

 

                     User1 user = new User1();

                     user.setName("李四");

                     user.setPassword("123");

                     user.setCreateTime(new Date());

                     user.setExpireTime(new Date());

                    

                     // user的主键生成策略采用的是uuid,由hibernate框架提供id

                            //调用完成save后,会执行如下操作:

                            //在临时队列(ActionQueue)insert集合中存储user信息

                            //user纳入到了session(persistenContext)的管理,并将userexistsInDatebase状态为false

                     //不会发出insert语句,数据库中无user的相关信息

                     session.save(user);

                    

                            //调用flushhibernate会清理临时队列,发出sql,并且将sessionpersistentContext中的user对象的existsInDatebase状态为true

                            //如果数据库的隔离级别设置为未提交读,那么我们可以看到flush过的数据

                     session.flush();

                    

                            //默认情况下commit操作会先执行flush清理缓存,所以不用显示的调用flush

                            //commit后数据是无法回滚的

                     tx.commit();

              }catch(Exception e) {

                     e.printStackTrace();

                     tx.rollback();

              }finally {

                     HibernateUtils.closeSession(session);

              }

       }

      

       /**

        * 测试native主键生成策略

        */

       public void testSave2() {

              Session session = null;

              Transaction tx = null;

              try {

                     session = HibernateUtils.getSession();

                     tx = session.beginTransaction();

 

                     User2 user = new User2();

                     user.setName("张三1");

                     user.setPassword("123");

                     user.setCreateTime(new Date());

                     user.setExpireTime(new Date());

                    

                          // user的主键生成策略为native,id值由数据库提供

                            //调用session.save后,会执行如下操作

                            //不会在临时队列的insert集合中添加信息

                            //直接发出insert语句,返回有数据库生成的id

                            //纳入了session的管理,并将session中(persistentContextuser对象)existsInDatebase状态置为true

                            //如果数据库的隔离级别设置为为提交读,那么我们可以看到save过的数据

                     session.save(user);

                     tx.commit();

              }catch(Exception e) {

                     e.printStackTrace();

                     tx.rollback();

              }finally {

                     HibernateUtils.closeSession(session);

              }

       }

      

      

       /**

        * 测试uuid主键生成策略

        */

       public void testSave3() {

              Session session = null;

              Transaction tx = null;

              try {

                     session = HibernateUtils.getSession();

                     tx = session.beginTransaction();

 

                     User1 user = new User1();

                     user.setName("王五");

                     user.setPassword("123");

                     user.setCreateTime(new Date());

                     user.setExpireTime(new Date());

                    

                     //因为user的主键生成策略采用的是uuidhibernate提供id值)

                            //所以调用完成save后,只是将user纳入到了session的管理,并在临时队列中存储待插入信息

                            //不会发出insert语句,但是id已经生成,sessionexistsInDatebase状态为false

                     session.save(user);

                    

                     //user对象从session缓存中逐出,即sessionpersistentContext中不保存user对象

                     session.evict(user);

                    

                     //无法成功提交,因为hibernate在清理临时队列时,从sessioninsertions集合中取出user对象进行insert操作后,然后会更新persistentContextuserexistsInDatabase属性的值为true,但是由于evict已经将usersession缓存(persistentContext)中清除,所以无法找到相应对象,此时抛出异常

                     tx.commit();

              }catch(Exception e) {

                     e.printStackTrace();

                     tx.rollback();

              }finally {

                     HibernateUtils.closeSession(session);

              }

       }

      

       /**

        * 测试uuid主键生成策略

        */

       public void testSave4() {

              Session session = null;

              Transaction tx = null;

              try {

                     session = HibernateUtils.getSession();

                     tx = session.beginTransaction();

 

                     User1 user = new User1();

                     user.setName("王五");

                     user.setPassword("123");

                     user.setCreateTime(new Date());

                     user.setExpireTime(new Date());

                    

                            // user的主键生成策略采用的是uuid

                            //调用save后,发生如下操作

                            //在临时队列中保存待插入信息

                            //user纳入到了session缓存(persistentContext)的管理,existsInDatebase状态为false

                            //而不会发出insert语句

                     session.save(user);

                    

                       //flush后,会执行如下操作

                            //hibernate会清理临时队列(session activeQueue中的insertions中的user对象清除)

                            //发出sql语句并将user对象保存到数据库中

                            //设置session persistentContext中该对象的existsInDatebase的状态为true

                     session.flush();

                    

                     //user对象从session缓存中逐出

                     session.evict(user);

                    

                     //可以成功提交,因为hibernate在清理临时队列时,在sessioninsertions集合中无法找到user对象

                            //所以就不会发出insert语句,也不会更新session中的existsInDatabase的状态

                     tx.commit();

              }catch(Exception e) {

                     e.printStackTrace();

                     tx.rollback();

              }finally {

                     HibernateUtils.closeSession(session);

              }

       }

      

       /**

        * 测试native主键生成策略

        */

       public void testSave5() {

              Session session = null;

              Transaction tx = null;

              try {

                     session = HibernateUtils.getSession();

                     tx = session.beginTransaction();

 

                     User2 user = new User2();

                     user.setName("张三11");

                     user.setPassword("123");

                     user.setCreateTime(new Date());

                     user.setExpireTime(new Date());

                    

                     //因为user的主键生成策略为native,所以调用session.save后,将执行insert语句,返回由数据库生成的id

                            //不会在临时队列中存储该对象的待插入信息

                            //纳入了session缓存的管理,修改了sessionexistsInDatebase状态为true

                            //如果数据库的隔离级别设置为为提交读,那么我们可以看到save过的数据

                     session.save(user);

                    

                     //user对象从session缓存中逐出,即sessionpersistentContext中逐出

                     session.evict(user);

                    

                     //可以成功提交,因为hibernate在清理缓存时,在sessioninsertions集合中无法找到user对象

                            //所以就不会发出insert语句,也不会更新session缓存中该对象的existsInDatabase的状态

                     tx.commit();

              }catch(Exception e) {

                     e.printStackTrace();

                     tx.rollback();

              }finally {

                     HibernateUtils.closeSession(session);

              }

       }

      

       /**

        * 测试assigned主键生成策略

        *

        */

       public void testSave6() {

              Session session = null;

              Transaction tx = null;

              try {

                     session = HibernateUtils.getSession();

                     tx = session.beginTransaction();

 

                     User3 user = new User3();

                     user.setId("001");

                     user.setName("张三");

                    

                     session.save(user);

                    

                     user.setName("王五");

                     session.update(user);

                    

                     User3 user3 = new User3();

                     user3.setId("002");

                     user3.setName("李四");

                     session.save(user3);

                    

                     //Hibernate: insert into t_user3 (name, password, create_time, expire_time, user_id) values (?, ?, ?, ?, ?)

                            //Hibernate: insert into t_user3 (name, password, create_time, expire_time, user_id) values (?, ?, ?, ?, ?)

                            //Hibernate: update t_user3 set name=?, password=?, create_time=?, expire_time=? where user_id=?

                            //hibernate按照save(insert),updatedelete顺序提交相关操作

                     tx.commit();

              }catch(Exception e) {

                     e.printStackTrace();

                     tx.rollback();

              }finally {

                     HibernateUtils.closeSession(session);

              }

       }    

      

       /**

        * 测试assigned主键生成策略

        *

        */

       public void testSave7() {

              Session session = null;

              Transaction tx = null;

              try {

                     session = HibernateUtils.getSession();

                     tx = session.beginTransaction();

 

                     User3 user = new User3();

                     user.setId("003");

                     user.setName("张三");

                    

                     session.save(user);

                    

                     user.setName("王五");

                     session.update(user);

                    

                     session.flush();

                    

                     User3 user3 = new User3();

                     user3.setId("004");

                     user3.setName("李四");

                     session.save(user3);

                    

                     //Hibernate: insert into t_user3 (name, password, create_time, expire_time, user_id) values (?, ?, ?, ?, ?)

                            //Hibernate: update t_user3 set name=?, password=?, create_time=?, expire_time=? where user_id=?

                            //Hibernate: insert into t_user3 (name, password, create_time, expire_time, user_id) values (?, ?, ?, ?, ?)

                            //因为我们在session.udpate(user)后执行了flush,所以在清理缓存时执行flush前的sql不会生成

                            //sql会按照我们的意愿执行

                     tx.commit();

              }catch(Exception e) {

                     e.printStackTrace();

                     tx.rollback();

              }finally {

                     HibernateUtils.closeSession(session);

              }

       }           

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值