flush与session的内部执行的过程详解

来源:互联网 发布:淘宝促销广告语 编辑:程序博客网 时间:2024/05/16 11:24

1.当主键生成策略是uuid的时候的情况 (这时候save的时候,不会发出sql的语句) :

   User1 user = new User1();   user.setName("李四");   user.setPassword("123");   user.setCreateTime(new Date());   user.setExpireTime(new Date());   //因为user的主键生成侧路采用的是uuid,所以调用完成save后,只是将user纳入到了session的管理   //不会发出insert语句,但是id已经生成,session中existsInDatebase状态为false   session.save(user);

内部执行的过程: 当save的时候,session放了三份对象:一份对象是放在actionQueue的insertions的缓存中,一份对象是放在持久化上下文中。还有一份快照放在一个你看不见的地方,我也不知道在哪里. 而且我猜想,当save的时候,虽然没有发出sql的语句。但是会使用一种方法将sql语句存到一个地方。 eg: insert into values ("张三"); 然后给内存拍一张照片放在一个地方。当将张三改为李四的时候,缓存和上下文的对象属性都变成了李四。但是快照中还是张三,在flush的方法的时候,会将缓存中的东西和快照中的东西进行比较,然后发出  update user set name = '李四'; flush完成之后会清理缓存,最后修改持久化上下文中的existsInDatabase改为true。

总的来说:它不会根据缓存中的insertions的内容发出 insert  into user values ('李四');

                  而是先发:insert  into user values ('李四');

                  然后再发:update user set name = '李四';

一定要彻底理解: sql 语句是根据什么生成的!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

如图:

 

 

 

2.当主键生成策略是native的时候的情况 (这时候save的时候,会发出sql的语句) :

  这个时候直接生成了sql的语句,所以缓存中不会有任何的数据!!!更不会有快照,和存储sql的语句。但是持久化上下文中有对象。

 

3. evict的方法含义:是清除持久化上下文中的对象,而不是清理缓存。

   session.save(user);       //发出sql的语句(native的生成策略),并且缓存没有数据,上下文中有数据
   session.evict(user);       // 缓存中没有数据,上下文中没有数据
   tx.commit();                   // 脏数据的检查,因为缓存中没有数据,更没有快照比对所以不会发出任何的语句。

   session.save(user)       // 不会发出sql的语句(uuid的生成策略情况),有缓存,有快照,还藏着一条insert的语句,上下文中有数据

   session.evict(user);      // 缓存中数据不变,上下文中没有数据

   tx.commit();                  //  提交的时候,会先发出藏着的sql的语句,然后脏数据的检查,清理缓存。最后再修改上下文中的            existsInDatabase 属性变为true。但是此时没有任何的数据,所以会报错哦!!

 

4.  如果你理解了我上面说的内部执行的过程,那么你就知道下面执行语句的顺序了

   eg:

        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);

结果是先两个insert的语句,最后update语句。

解决办法:

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);


亲:一定要彻底理解哦!