zoukankan      html  css  js  c++  java
  • hibernate学习(5)——对象状态与一级缓存

    1、对象状态

    1.1   状态介绍

     hibernate 规定三种状态:瞬时态、持久态、脱管态

           瞬时态:transient,session没有缓存对象,数据库也没有对应记录。没有与hibernate关联,与数据库中的记录没有产生关联。

                  OID特点:没有值

           持久态:persistent,session缓存对象,数据库最终会有记录。(事务没有提交)与hibernate关联,对象有id

                  OID特点:有值

           脱管态:detached,session没有缓存对象,数据库有记录。没有与hibernate关联,对象有id

                  OID特点:有值

    1.2 对象转换

    1.2.1 瞬时态/临时态

    1  获得:一般都只直接创建(new)

    2  瞬时态 转换 持久态

           一般操作:save方法、saveOrUpdate

    3 瞬时态 转换 脱管态

           一般操作:通过setId方法设置数据

    例如:

           User user = new User();        //瞬时态

           user.setUid(1);                            //脱管态

    1.2.2 持久态

    1 获得:

           查询操作:get、loat、createQuery、createCriteria 等 获得都是持久态【】

           执行save之后持久态

           执行update之后持久态

    2  持久态 转换 瞬时态

           官方规定执行delete()  --民间:删除态

    3  持久态 转换 脱管态

           session没有记录

                  session.close () 关闭

                  session.clear() 清除所有

                  session.evict(obj) 清除指定的PO对象

    1.2.3   脱管态/游离态

    1  获得:

           创建、并设置OID的

           通过api获得

    2 脱管态 转换 瞬时态

           手动去除OID,设置成默认值

    3  脱管态 转换 持久态

           一般操作:update()、saveOrUpdate

    总结:

    持久状态,我们使用Hibernate主要是为了持久化我们的数据.
     对于对象的状态,我们期望我们需要同步到数据库的数据,都被装换成持久状态
    /持久化状态特点: Hibernate会自动将持久化状态对象的变化同步到数据库中

    代码实现:

    package com.alice.hibernate02.a_statue;
    
    import org.hibernate.Session;
    import org.hibernate.Transaction;
    import org.junit.Test;
    
    import com.alice.hibernate02.util.HibernateUtil;
    import com.alice.hibernate02.vo.User;
    
    public class Status01Test {
        @Test
        //演示三种状态
        public void statue01Test(){
            Session session = HibernateUtil.openSession();
            
            Transaction tran = session.beginTransaction();
            
            User user = new User();// 瞬时状态
            user.setName("lili");// 瞬时状态
            user.setPassword("12233");// 瞬时状态
            
            session.save(user);// 持久状态调用完save方法,数据库中有没有对应记录?
            // 没有对应记录, 但是最终会被同步到数据库中.仍然是持久状态.
            
            tran.commit();//持久状态
            
            session.close();//游离状态
            
        }
        @Test
        public void statue02Test(){
            Session session = HibernateUtil.openSession();
            
            Transaction tran = session.beginTransaction();
            
            User user = new User();// 瞬时状态
            user.setName("lili");// 瞬时状态
            user.setPassword("12233");// 瞬时状态
            
            session.save(user);//save方法会使用主键生成策略,为User指定id.
            //主键自增 => 打印 insert语句
            // increment=> select max(id) ....
            //assigned => 需要手动指定主键,不指定将会报错
            
            tran.commit();
            session.close();
        }
            @Test
            // 瞬时=> 游离
            // 瞬时: 没有关联,没有id
            // 游离: 没有关联,有id(与数据库中对应的id)
        public void statue03Test(){
                Session session = HibernateUtil.openSession();
                
                Transaction tran = session.beginTransaction();
                
                //............
                User user = new User();//瞬时态
                
                user.setId(1);//游离态
                
                //----------------------------------------------------
                session.getTransaction().commit(); // 持久状态
                                            //事务提交时,会把持久化状态对象同步到数据库中
                session.close(); // 游离状态
        }
    //        @Test
            // 持久=> 瞬时
            // 持久: 有关联,有id
            // 瞬时: 无关联,无id
    //        public void statue04Test(){
    //            Session session = HibernateUtil.openSession();
    //            
    //            Transaction tran = session.beginTransaction();
    //            
    //            //............
    //            //通过get方法,得到持久状态对象
    //            User user = (User) session.get(User.class, 1);
    //            
    //            
    //            //----------------------------------------------------
    //            session.getTransaction().commit(); // 持久状态
    //                                        //事务提交时,会把持久化状态对象同步到数据库中
    //            session.close(); // 游离状态
    //            
    //            user.setId(null);//瞬时态
    //    }
            @Test
            // 持久=> 游离
            // 只需要将session的关联取消
            public void statue05Test(){
                Session session = HibernateUtil.openSession();
                
                Transaction tran = session.beginTransaction();
                
                //............
                User user = new User();//瞬时态
                
                session.evict(user);//游离
                
                //----------------------------------------------------
                session.getTransaction().commit(); // 持久状态
                                            //事务提交时,会把持久化状态对象同步到数据库中
                session.close(); // 游离状态
        }
            @Test
            // 游离=> 瞬时
            // 移除ID 
            public void statue06Test(){
                Session session = HibernateUtil.openSession();
                
                Transaction tran = session.beginTransaction();
                
                //............
                User user = new User();//瞬时态
                
                session.evict(user);//游离
                
                user.setId(null);//瞬时
                //----------------------------------------------------
                session.getTransaction().commit(); // 持久状态
                                            //事务提交时,会把持久化状态对象同步到数据库中
                session.close(); // 游离状态
        }    
            @Test
            // 游离=> 持久
            // 是否与Session关联
        public void fun8(){
            Session session = HibernateUtil.openSession();
            session.beginTransaction();
            //------------------------------------------------
                //通过get方法,得到持久状态对象
            User u= (User) session.get(User.class, 1); // 持久状态
            
            session.evict(u);//游离
            
            session.update(u);//持久
            //----------------------------------------------------
            session.getTransaction().commit(); // 持久状态 -> 打印update语句
            session.close(); // 瞬时状态
        }
            
    }

    2、  一级缓存

    2.1 介绍session缓存

    一级缓存:又称为session级别的缓存。当获得一次会话(session),hibernate在session中创建多个集合(map),用于存放操作数据(PO对象),为程序优化服务,如果之后需要相应的数据,hibernate优先从session缓存中获取,如果有就使用;如果没有再查询数据库。当session关闭时,一级缓存销毁。

    //证明session缓存的存在
        public void statue01Test(){
            Session session = HibernateUtil.openSession();
            
            Transaction tran = session.beginTransaction();
            
            User user1 = (User) session.get(User.class, 1);// 发送select语句,从数据库取出记录.并封装成对象
               // 持久化状态对象=> 存到缓存中
            System.out.println("user1"+user1);
            
            User user2 = (User) session.get(User.class, 1);//再次查询时,会从缓存中查找,不会发送select
            System.out.println("user2"+user2);
            
            System.out.println(user1 == user2);
            
            tran.commit();//持久状态
            
            session.close();//游离状态
            
        }

    2.2   一级缓存快照

    l  快照:与一级缓存一样的存放位置,对一级缓存数据备份。保证数据库的数据与 一级缓存的数据必须一致。如果一级缓存修改了,在执行commit提交时,将自动刷新一级缓存,执行update语句,将一级缓存的数据更新到数据库。

    @Test
    	//session缓存中的快照
    	 public void cache02Test(){
    	    	Session session = HibernateUtil.openSession();
    	    	
    	    	Transaction tran = session.beginTransaction();
    	    	
    	    	User user1 = (User) session.get(User.class, 1);// 发送select语句,从数据库取出记录.并封装成对象
    			 
    	    	session.update(user1);
    	    	
    	    	tran.commit();//持久状态
    	    	
    	    	session.close();//游离状态
    	    	
    	    }
    	@Test
    	//session缓存中的快照
    	public void cache03Test(){
        	Session session = HibernateUtil.openSession();
        	
        	Transaction tran = session.beginTransaction();
        	
        	User user1 = new User();
        	
        	user1.setId(1);
        	user1.setName("aaaa");
        	user1.setPassword("1435");
    		 
        	session.update(user1);
        	
        	tran.commit();//持久状态
        	
        	session.close();//游离状态
        	
        }
    

      

    // 持久化状态: 本质就是存在缓存中的对象,就是持久化状态.

    2.3 缓冲区

    package com.alice.hibernate02.a_statue;
    
    import java.util.List;
    
    import org.hibernate.Session;
    import org.hibernate.Transaction;
    import org.junit.Test;
    
    import com.alice.hibernate02.util.HibernateUtil;
    import com.alice.hibernate02.vo.User;
    
    //session缓存 的细节问题
    public class DetailsTest {
        @Test
        // 1.保存对象时使用 save方法
        // 保存对象时使用 persist方法
        // 区别? 没有区别
        // persist(持久) 方法 来自于JPA 接口
        // save(保存) 方法来自于Hibernate
        public void details01Test() {
            Session session = HibernateUtil.openSession();
    
            Transaction tran = session.beginTransaction();
    
            User user = new User();// 瞬时状态
            user.setName("lili");// 瞬时状态
            user.setPassword("12233");// 瞬时状态
    
            // session.save(user);// insert 语句被打印,读取id
            session.persist(user);
            tran.commit();// 持久状态
    
            session.close();// 游离状态
    
        }
    
        // HQL查询一般不会使用缓存
        @Test
        public void details02Test() {
            Session session = HibernateUtil.openSession();
    
            Transaction tran = session.beginTransaction();
    
            List<User> list1 = session.createQuery("from User").list();
    
            List<User> list2 = session.createQuery("from User").list();
    
            List<User> list3 = session.createQuery("from User").list();
    
            tran.commit();// 持久状态
            session.close();// 游离状态
    
        }
    
        @Test
        // HQL语句批量查询时,查询结果会存入缓冲区
        public void details03Test() {
            Session session = HibernateUtil.openSession();
    
            Transaction tran = session.beginTransaction();
    
            List<User> list1 = session.createQuery("from User").list();
    
            User user = (User) session.get(User.class, 1);
    
            tran.commit();// 持久状态
            session.close();// 游离状态
    
        }
    
        @Test
        // SQL查询,如果把查询结果封装到对象中,对象会放入一级缓存
        public void details04Test() {
            Session session = HibernateUtil.openSession();
    
            Transaction tran = session.beginTransaction();
    
            List<User> list1 = session.createSQLQuery("select * from t_ser")
                    .addEntity(User.class).list();
            User u = (User) session.get(User.class, 1);
    
            System.out.println(u);
    
            tran.commit();// 持久状态
            session.close();// 游离状态
    
        }
    
        @Test
        // SQL查询,没有把查询结果封装到对象中,对象不会放入一级缓存
        public void details05Test() {
            Session session = HibernateUtil.openSession();
    
            Transaction tran = session.beginTransaction();
    
            List<User> list1 = session.createSQLQuery("select * from t_ser").list();
            User u = (User) session.get(User.class, 1);
    
            System.out.println(u);
    
            tran.commit();// 持久状态
            session.close();// 游离状态
    
        }
        //criteria => 会将查询结果放入一级缓存. 但是查询不会使用一级缓存. 与Hql查询结论一致.
    }

    //问题: 缓存中的数据如果与数据库中的不同步,会怎么样?
    // 会优先使用缓存中的. 使用JDBC
    // 在一级缓存中出现该问题的几率比较小.
    //openSession==> 一级缓存生命周期开始
    //session.close();=> 一级缓存销毁

    2.4 其他api

    package com.alice.hibernate02.api;
    
    import org.hibernate.Session;
    import org.hibernate.Transaction;
    import org.junit.Test;
    
    import com.alice.hibernate02.util.HibernateUtil;
    import com.alice.hibernate02.vo.User;
    
    //其他API (大部分都是了解)
    public class SessionTest {
        @Test
        // 1. evict 将缓存中的对象移除.
        // 2. clear 清空1级缓存
        public void session01Test() {
            Session session = HibernateUtil.openSession();
    
            Transaction tran = session.beginTransaction();
    
            User user = (User) session.get(User.class, 21);
            session.clear();
    
            session.getTransaction().commit();
            session.close();// 游离状态
    
        }
    
        @Test
        // 3 refresh 刷新 => 强制刷新缓存中的对象 => (可以用来解决缓存与数据库数据不同步的问题)
        public void session02Test() {
            Session session = HibernateUtil.openSession();
    
            Transaction tran = session.beginTransaction();
    
            User user = (User) session.get(User.class, 9);
            session.refresh(user);// 将缓存中的对象立刻与数据库同步,会再发送一个sql语句
    
            session.getTransaction().commit();
            session.close();// 游离状态
    
        }
    
        @Test
        // 4 flush 对比快照,并提交缓存对象
        public void session03Test() {
            Session session = HibernateUtil.openSession();
    
            Transaction tran = session.beginTransaction();
    
            User user = (User) session.get(User.class, 9);
            session.flush();// 将缓存中的对象立刻与数据库同步,会再发送一个sql语句
    
            session.getTransaction().commit();
            session.close();// 游离状态
    
        }
    
        @Test
        // 代理主键=> native
        // 5.1 aveOrUpdate方法
        // saveOrUpdate 可以同时完成保存或更新操作
        // 主键为空=>save
        // 主键有值=> update
        // 自然主键=> assigned
        // 5 update 与 saveOrUpdate方法
        // saveOrUpdate 可以同时完成保存或更新操作
        // 主键为空=> 报错,因为无论是save还是update 都必须指定id
        // 主键有值=> 先会根据主键查询数据库.
        // 数据库中存在=> 执行update
        // 数据库中不存在=> 执行insert
        public void session04Test() {
            Session session = HibernateUtil.openSession();
    
            Transaction tran = session.beginTransaction();
    
            User user = new User();
            user.setId(1);
            user.setName("lilaa");
            user.setPassword("143325");
            session.saveOrUpdate(user);
    
            session.getTransaction().commit();
            session.close();// 游离状态
    
        }
        //在我们使用Hibernate时候,注意要避免出现,两个相同的ID对象.放入一级缓存的情况.
        @Test
        public void session05Test() {
            Session session = HibernateUtil.openSession();
    
            Transaction tran = session.beginTransaction();
    
            User user = (User) session.get(User.class, 1);// 持久化,缓存中存在
            session.evict(user); // 游离态,缓存中不存在
            
            User user1 = (User) session.get(User.class, 1);// 持久化,缓存中存在
            
            session.update(user);// 将user重新变为持久化状态,缓存中存在
            
            
            session.getTransaction().commit();
            session.close();// 游离状态
    
        }
    }
  • 相关阅读:
    简单工厂笔记
    P3369 【模板】普通平衡树 Treap树堆学习笔记
    tp5阿里云短信验证码
    centos 安装php
    tp6.0.2开启多应用模式
    linux navicat最新版过期
    git commit之后 取消commit
    服务器重置之后ssh root@报错
    git pull push 每次都需要输入账号和密码
    跨域问题 php
  • 原文地址:https://www.cnblogs.com/snowwang/p/6123481.html
Copyright © 2011-2022 走看看