zoukankan      html  css  js  c++  java
  • hibernate04--三种状态之间的转换

    public class StudentTest {
        
        
        
        Session session=null;
        Transaction transaction=null;
        //在执行测试方法之前 先执行before
        @Before
        public  void  before(){
            /**
             * 01.读取核心的配置文件  在src的根目录下面! 底层规定位置!
             *   在实例化Configuration对象的时候通过configure()
             *   去src根目录下面,寻找hibernate.cfg.xml文件
             */
            Configuration configuration=new Configuration().configure();
            //02.创建sessionFactory
            SessionFactory sessionFactory = configuration.buildSessionFactory();
            //03.打开session
             session = sessionFactory.openSession();
            //04.开启事务
             transaction= session.beginTransaction();
        }
        
        
        //在执行测试方法之后 
        @After
        public  void  after(){
             //07.提交事务  sql语句 整体的执行!
             transaction.commit();
             //08.关闭session
             session.close();
             //sessionFactory.close(); 验证hbm2ddl中的create-drop
        }
        
        
        /**
         * hibernate对象的三种状态!
         * 01.瞬时状态(临时状态/自由状态)
         *     我们通过new关键字 创建出的一个实体对象!和hibernate没有半毛钱关系!
         * 
         * 02.持久状态
         *    对象正在被session管理,数据库中有对象 对应的数据!
         *    如果对象是持久状态!  那么对它的修改操作   不需要再使用其他的方法(update)
         *    在commit的时候,会执行flush(),
         *    flush()的时候会进行缓存清理!
         *    缓存清理的时候会进行脏检查!
         *    如果对象的属性和之前的对象属性不一致!
         *    那么当前的对象就是脏对象!
         *    就会把脏对象同步到数据库!
         * 
         * 03.游离状态(脱管状态)
         *     曾经被session管理过!和瞬时状态的区别就是 是否存在OID(主键标识符)!
         *     
         */
        
        @Test
        public  void  testSave1(){
            //创建一个对象
            Student  stu=new Student(100, 50, "老白");  //瞬时状态
            session.save(stu);   //持久化状态
            stu.setName("老白干");  
            /**
            改变了对象的属性   这时候的stu就是脏对象  不需要执行update()
            commit的时候会产生两条sql语句!
              01.insert
              02.update
            */
        }
        
        
        @Test
        public  void  testSave02(){
            //创建一个对象
            Student  stu=new Student(666, 50, "老白");  //瞬时状态
            stu.setName("老白干");  //瞬时状态
            session.save(stu);   //持久化状态   从这里开始 才被 session管理!
        }
        
        @Test
        public  void  testSave03(){
            //创建一个对象
            Student  stu=new Student(555, 50, "老白");  //瞬时状态
            stu.setName("老白干");  //瞬时状态
            session.save(stu);   //持久化状态   从这里开始 才被 session管理!
            stu.setName("老白干1");  
            stu.setName("老白干2");  
            stu.setName("老白干3");  
            /**
             * 还是两条sql语句
             *commit的时候会产生两条sql语句!
              01.insert
              02.update
             */
        }
        
        
        /**
         * 测试方法的前提环境三种情况
         *    01.stu对象在数据库中没有对应的数据
         *    02.stu对象在数据库中有对应的数据,但是我们没有修改属性
         *    03.stu对象在数据库中有对应的数据,我们修改了属性
         * 产生的结果都是一致的!
         *  根据id  产生update语句 
         */
        @Test
        public  void  testUpdate(){
            //创建一个对象
            Student  stu=new Student(1, 50, "老白");  //瞬时状态
            session.update(stu);
        }
        
        
        /**
         * 测试方法的前提环境
         *    stu对象在数据库中没有对应的数据
         * 产生的结果:
         *   01.根据id 产生 select
         *   02.发现数据库中没有对应的数据  产生  insert
         */
        @Test
        public  void  testSaveOrUpdate(){
            //创建一个对象
            Student  stu=new Student(1, 50, "老白");  //瞬时状态
            session.saveOrUpdate(stu);
        }
        
        /**
         * 测试方法的前提环境
         *    01.stu对象在数据库有对应的数据  
         *    02.没有改变stu对象的属性值
         * 产生的结果:
         *    根据id 产生 select语句
         */
        @Test
        public  void  testSaveOrUpdate2(){
            //创建一个对象
            Student  stu=new Student(1, 50, "老白");  //瞬时状态
            session.saveOrUpdate(stu);
        }
        
        /**
         * 测试方法的前提环境
         *    01.stu对象在数据库有对应的数据  
         *    02.改变了stu对象的属性值
         * 产生的结果:
         *    01.根据id 产生 select
         *    02.因为修改了对象的属性 所以 执行update
         */
        @Test
        public  void  testSaveOrUpdate3(){
            //创建一个对象
            Student  stu=new Student(1, 50, "老白");  //瞬时状态
            stu.setName("老白干");
            session.saveOrUpdate(stu);
        }
        
    }
    
    

    package cn.bdqn.test;
    
    import org.hibernate.Session;
    import org.hibernate.SessionFactory;
    import org.hibernate.Transaction;
    import org.hibernate.cfg.Configuration;
    import org.junit.After;
    import org.junit.Before;
    import org.junit.Test;
    
    import cn.bdqn.bean.Student;
    
    
    public class StudentTest {
        
        
        
        Session session=null;
        Transaction transaction=null;
        //在执行测试方法之前 先执行before
        @Before
        public  void  before(){
            /**
             * 01.读取核心的配置文件  在src的根目录下面! 底层规定位置!
             *   在实例化Configuration对象的时候通过configure()
             *   去src根目录下面,寻找hibernate.cfg.xml文件
             */
            Configuration configuration=new Configuration().configure();
            //02.创建sessionFactory
            SessionFactory sessionFactory = configuration.buildSessionFactory();
            //03.打开session
             session = sessionFactory.openSession();
            //04.开启事务
             transaction= session.beginTransaction();
        }
        
        
        //在执行测试方法之后 
        @After
        public  void  after(){
             //07.提交事务  sql语句 整体的执行!
             transaction.commit();
             //08.关闭session
             session.close();
             //sessionFactory.close(); 验证hbm2ddl中的create-drop
        }
        
        
        /**
         * hibernate对象的三种状态!
         * 01.瞬时状态(临时状态/自由状态)
         *     我们通过new关键字 创建出的一个实体对象!和hibernate没有半毛钱关系!
         * 
         * 02.持久状态
         *    对象正在被session管理,数据库中有对象 对应的数据!
         *    如果对象是持久状态!  那么对它的修改操作   不需要再使用其他的方法(update)
         *    在commit的时候,会执行flush(),
         *    flush()的时候会进行缓存清理!
         *    缓存清理的时候会进行脏检查!
         *    如果对象的属性和之前的对象属性不一致!
         *    那么当前的对象就是脏对象!
         *    就会把脏对象同步到数据库!
         * 
         * 03.游离状态(脱管状态)
         *     曾经被session管理过!和瞬时状态的区别就是 是否存在OID(主键标识符)!
         *     
         */
        
        @Test
        public  void  testSave1(){
            //创建一个对象
            Student  stu=new Student(100, 50, "老白");  //瞬时状态
            session.save(stu);   //持久化状态
            stu.setName("老白干");  
            /**
            改变了对象的属性   这时候的stu就是脏对象  不需要执行update()
            commit的时候会产生两条sql语句!
              01.insert
              02.update
            */
        }
        
        
        @Test
        public  void  testSave02(){
            //创建一个对象
            Student  stu=new Student(666, 50, "老白");  //瞬时状态
            stu.setName("老白干");  //瞬时状态
            session.save(stu);   //持久化状态   从这里开始 才被 session管理!
        }
        
        @Test
        public  void  testSave03(){
            //创建一个对象
            Student  stu=new Student(555, 50, "老白");  //瞬时状态
            stu.setName("老白干");  //瞬时状态
            session.save(stu);   //持久化状态   从这里开始 才被 session管理!
            stu.setName("老白干1");  
            stu.setName("老白干2");  
            stu.setName("老白干3");  
            /**
             * 还是两条sql语句
             *commit的时候会产生两条sql语句!
              01.insert
              02.update
             */
        }
        
        
        /**
         * 测试方法的前提环境三种情况
         *    01.stu对象在数据库中没有对应的数据
         *    02.stu对象在数据库中有对应的数据,但是我们没有修改属性
         *    03.stu对象在数据库中有对应的数据,我们修改了属性
         * 产生的结果都是一致的!
         *  根据id  产生update语句  ! 只能是从游离变持久!
         */
        @Test
        public  void  testUpdate(){
            //创建一个对象
            Student  stu=new Student(1, 50, "老白");  //瞬时状态
            session.update(stu); 
        }
        
        
        /**
         * 测试方法的前提环境
         *    stu对象在数据库中没有对应的数据
         * 产生的结果:
         *   01.根据id 产生 select
         *   02.发现数据库中没有对应的数据  产生  insert
         */
        @Test
        public  void  testSaveOrUpdate(){
            //创建一个对象
            Student  stu=new Student(1, 50, "老白");  //瞬时状态
            session.saveOrUpdate(stu);
        }
        
        /**
         * 测试方法的前提环境
         *    01.stu对象在数据库有对应的数据  
         *    02.没有改变stu对象的属性值
         * 产生的结果:
         *    根据id 产生 select语句
         */
        @Test
        public  void  testSaveOrUpdate2(){
            //创建一个对象
            Student  stu=new Student(1, 50, "老白");  //瞬时状态
            session.saveOrUpdate(stu);
        }
        
        /**
         * 测试方法的前提环境
         *    01.stu对象在数据库有对应的数据  
         *    02.改变了stu对象的属性值
         * 产生的结果:
         *    01.根据id 产生 select
         *    02.因为修改了对象的属性 所以 执行update
         */
        @Test
        public  void  testSaveOrUpdate3(){
            //创建一个对象
            Student  stu=new Student(1, 50, "老白");  //瞬时状态
            stu.setName("老白干");
            session.saveOrUpdate(stu);
        }
        
        
        
        /**
         * 测试方法的前提环境
         *      stu对象在数据库没有对应的数据  
         * 产生的结果:
         *  两条sql
         *   01.select  先去数据库中查询有没有id对应的数据
         *   02.执行 insert
         */
        @Test
        public  void  testMerge01(){
            Student  stu=new Student(1, 50, "老白");  //瞬时状态
            session.merge(stu);
        }
        /**
         * 测试方法的前提环境
         *      stu对象在数据库有对应的数据  ,我们没有修改对象的属性
         * 产生的结果:
         *     只有select语句
         */
        @Test
        public  void  testMerge02(){
            Student  stu=new Student(1, 50, "老白");  //瞬时状态
            session.merge(stu);
        }
        
        /**
         * 测试方法的前提环境
         *      stu对象在数据库有对应的数据  ,我们修改了对象的属性
         * 产生的结果:
         *  01.select
         *  02.update
         */
        @Test
        public  void  testMerge03(){
            Student  stu=new Student(1, 50, "老白");  //瞬时状态
            stu.setName("老白干");
            session.merge(stu);
        }
        
        /**
         * 测试方法的前提环境
         *     stu对象在数据库有对应的数据  ,我们修改了对象的属性
         * 产生的结果:
         *     报错
         */
        @Test
        public  void  testMerge04(){
            Student  stu=new Student(1, 50, "老白干");  //瞬时状态
            session.merge(stu);  //不会改变对象的状态
            stu.setName("老白11111");  //瞬时状态
            session.update(stu);  //报错
        }
        
        /**
         * save(): 把瞬时状态转换成  持久状态
         * update():把游离状态转换成  持久状态
         * saveOrUpdate():
         *   会根据持久化对象的主键标识符来判断是执行save()还是update()
         *      如果没有oid,证明是瞬时状态,就执行save();
         *      如果有oid,证明是游离状态,就执行update();
         * merge: 虽然和saveOrUpdate()产生的sql结果一致!
         *   但是:
         *     01.merge不会改变对象的状态!
         *     02.当对象处于瞬时状态的时候,会将对象赋值一份到session的缓存中,执行save() ,产生insert语句!
         *       我们认为 产生了 insert语句,stu就变成了持久化对象!其实不是!
         *       只不过是session缓存中的对象发生了变化!
         */
        
        
        
    }
    /**
     * 第一步:
     *01.读取配置文件  hibernate.cfg.xml
     *02.创建会话工厂---》确保工厂是单例模式
     *03.提供对外访问的接口
     *第二步:
     *  在核心配置文件中 管理我们的currentSession
     */
    public class HibernateSessionUtil {
         private  static  Configuration configuration;
         private static  SessionFactory sessionFactory;
         
         private  HibernateSessionUtil(){}//私有化构造
         
         //在类被加载的时候   执行静态代码块 
         static{
             configuration=new Configuration().configure();
             sessionFactory=configuration.buildSessionFactory();//获取会话工厂
         }
     
         //获取session的方法
         public  static Session  getCurrentSession(){
             return   sessionFactory.getCurrentSession();
         }
         
         
         
    }

    hibernate.cfg.xml文件中新增

    <!-- 配置我们的currentSession -->
        <property name="current_session_context_class">thread</property>

    测试代码

    public class SessionTest {
    
        public static void main(String[] args) {
            /**Configuration configuration=new Configuration().configure();
            SessionFactory sessionFactory = configuration.buildSessionFactory();
             Session session = sessionFactory.openSession(); //第一次
             System.out.println(session.hashCode());
             session = sessionFactory.openSession(); //第二次
             System.out.println(session.hashCode());  hashCode不一致
             */
            
            //通过我们自己创建的回话工厂来创建currentSession
             Session session = HibernateSessionUtil.getCurrentSession(); //第一次
             System.out.println(session.hashCode());
             session =  HibernateSessionUtil.getCurrentSession(); //第二次
             System.out.println(session.hashCode()); //hashCode一致
        }
    
    }
    /**
         *  flush和commit的区别!
         *  
         *  相同点:
         *     两者都会同步到数据库!
         *  
         *  不同点:
         *  commit:永久保存!  commit--->flush()-->缓存清理--->脏检查
         *  
         *  flush:  不会永久保存!     
         *  01.是执行缓存清理工作!
         *  02.会把缓存中的对象同步到数据库中!但是不会保存!
         *  03.确保缓存中的数据 和数据库中的数据一致!
         *  
         *  缓存清理机制:
         *    在我们执行flush()的时候,会清理session中的数据!
         *    在清理缓存的的时候,会执行脏检查!
         *  脏检查:
         *     在对象被session管理的时候!
         *     01.session会在缓存中创建出 对象的快照保存现在对象的一个状态以及属性! (a对象)   
         *     02.在清理缓存的时候会把现在对象的属性和(a对象)进行比对!
         *     03.发现现在的对象和(a对象不一致!那么现在的对象就称之为   脏对象!
         *     04.flush()会把这个脏对象 同步到 数据库! 但是不会保存!只是暂时的!
         *     05.之后commit的时候 才能永久保存数据!
         *  
         */
        @Test
        public  void test01(){
        //通过工具类获取session
            Session session = HibernateSessionUtil.getCurrentSession();
            //获取事务
            Transaction transaction = session.beginTransaction();
            Student  stu=(Student) session.get(Student.class, 1);//持久化对象
            stu.setName("能改变吗?");
            /**
             * 清理缓存
             * 按照我们的理解,没有commit是不可能提交事务的!言外之意!数据库中的数据不会改变!
             */
            System.out.println("*****************");
            session.flush();
            stu.setName("能改变吗2?");
            System.out.println("*****************");
            Student stu2=(Student) session.get(Student.class, 1);
            System.out.println(stu2.getName());  //已经改变了!
        }
        
        
        @Test
        public  void test02(){
            //通过工具类获取session
            Session session = HibernateSessionUtil.getCurrentSession();
            //获取事务
            Transaction transaction = session.beginTransaction();
            Student  stu=(Student) session.get(Student.class, 1);//持久化对象
            stu.setName("能改变吗?");
            System.out.println("*****************");
            session.flush();  //执行 sql
            stu.setName("能改变吗2?");  //之后又改变了 值
            System.out.println("*****************");
             /**
              * 缓存中的OID是一致的!
              * get()
              * 01.查询session缓存
              * 02.发现缓存中有数据  直接使用
              * 03.所以说  stu2的name必须是  “ 能改变吗2?”
              */
            Student stu2=(Student) session.get(Student.class, 1); 
            System.out.println(stu2.getName());  //改变了第2次!!  !
        }
  • 相关阅读:
    LeetCode347 前k个高频元素
    剑指42 连续字数租的最大和
    hdu1540
    hdu4553 两棵线段树
    cdq分治
    负环
    最短路
    差分约束系统
    hdu3308
    hdu5862 树状数组+扫描线+离散化
  • 原文地址:https://www.cnblogs.com/xtdxs/p/7093514.html
Copyright © 2011-2022 走看看