• 004---持久对象的生命周期介绍


    持久化对象的状态:

    1、   瞬时对象(Transient Object)使用new操作符初始化的对象不是立刻就持久的。它们的状态是瞬时的,也就是说它们没有任何跟数据库表相关联的行为,只要应用不再引用这些对象(不再被任何其它对象所引用),它们的状态将会丢失,并由垃圾回收机制回收

    2、   持久化对象(Persistent Object)持久实例是任何具有数据库标识的实例,它有持久化管理器Session统一管理,持久实例是在事务中进行操作的----它们的状态在事务结束时同数据库进行同步。当事务提交时,通过执行SQL的INSERT、UPDATE和DELETE语句把内存中的状态同步到数据库中。

    离线对象(Detached Object):Session关闭之后,持久化对象就变为离线对象。离线表示这个对象不能再与数据库保持同步,它们不再受hibernate管理

    Transient对象:随时可能被垃圾回收器回收(在数据库中没有于之对应的记录,应为是new初始化),而执行save()方法后,就变为Persistent对象(持久性对象),没有纳入session的管理

    Persistent对象:在数据库有存在的对应的记录,纳入session管理。在清理缓存(脏数据检查)的时候,会和数据库同步。

    Detached对象:也可能被垃圾回收器回收掉(数据库中存在对应的记录,只是没有任何对象引用它是指session引用),注引状态经过Persistent状态,没有纳入session的管理

    赃数据检查(版本比较)

    try {
                session = HibernateUtils.getSession();
                tx = session.beginTransaction();         
                //Transient状态
                user = new User();
                user.setName("李四");
                user.setPassword("123");
                user.setCreateTime(new Date());
                user.setExpireTime(new Date());
            
    
                /*
    
                 * persistent状态
    
                 * persistent状态的对象,当属性发生改变的时候,hibernate会自动和数据库同步
    
                 */
    
                session.save(user);          
                user.setName("王五");         
                tx.commit();
            } catch (Exception e) {
                e.printStackTrace();
                tx.rollback();
            } finally {
              HibernateUtils.closeSession(session);
            }

    session现在插入一条数据:User 对象name: 李四,现在需要修改数据,修改数据时采用数据版本的比较,修改之前对现有数据记录照一个快照(这个快照为最新数据“name:李四”),现在要User对象的name更改为五王(name:五王),当session提交事务之前时commit(),需要清理缓存(也称为賍数据对比),查看哪些数据需要发innert的SQL语句,而哪些需要发update语句。此处发出两条(第一条:为innert语句添加;第二条:在賍数据对比时发现数据发生改变,就发出update语句)

    Hibernate: insert into User (name, password, createTime, expireTime, id) values (?, ?, ?, ?, ?)

    Hibernate: update User set name=?, password=?, createTime=?, expireTime=? where id=?

    完整代码如下:

    public void testSave1(){
            Session session = null;
            Transaction tx = null;
            User user = null;
            
            try {
                session = HibernateUtils.getSession();
                tx = session.beginTransaction();
                
                //Transient状态
                user = new User();
                user.setName("李四");
                user.setPassword("123");
                user.setCreateTime(new Date());
                user.setExpireTime(new Date());
                
                /*
                 * persistent状态
                 * persistent状态的对象,当属性发生改变的时候,hibernate会自动和数据库同步
                 */
                session.save(user);
                
                user.setName("王五");
                //实际上user.setName("王五")此时已经发出一条update指令了。
                //也可以显示的调用update指定
                //session.update(user);
                
                tx.commit();
            } catch (Exception e) {
                e.printStackTrace();
                tx.rollback();
            } finally {
                HibernateUtils.closeSession(session);
            }
            
            /*
             * 从此处开始session已经在上面关闭,这时user对象状态就变为detached状态,
             * 所有user对象已经不被session管理,但数据库中确实存在与至对应的记录(王五)。
             */
            //detached状态
            user.setName("张三");
            
            try {
                session = HibernateUtils.getSession();
                session.beginTransaction();
                /*
                 * 此时session又对user对象进行管理
                 * 当session发出update指定后,进行更新数据为(张三。)
                 */
                session.update(user);
    
                //update后user对象状态又变为persistent状态
                session.getTransaction().commit();
                /*
                 * 此时session提交事务,发出update语句
                 * Hibernate: update User set name=?, password=?, createTime=?, expireTime=? where id=?
                 */
            } catch (HibernateException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
                session.getTransaction().rollback();
            }finally {
                HibernateUtils.closeSession(session);
            }
        }

    Hibernate加载数据:

             两种:get()、load()

    一、 Session.get(Class arg0, Serializable arg1)方法

    * arg0:需要加载对象的类,例如:User.class

        * arg1:查询条件(实现了序列化接口的对象):

    例"4028818a245fdd0301245fdd06380001"字符串已经实现了序列化接口。

        返回值: 此方法返回类型为Object,也就是对象,然后我们再强行转换为需要加载的对象就可以了。

                如果数据不存在,则返回null;

        注:执行此方法时立即发出查询SQL语句。加载User对象

     

    加载数据库中存在的数据,代码如下:

    try {
                session = sf.openSession();
                session.beginTransaction();
                
                /*
                 * Object org.hibernate.Session.get(Class arg0, Serializable arg1) throws HibernateException
                 * arg0:需要加载对象的类,例如:User.class
                 * arg1:查询条件(实现了序列化接口的对象):例"4028818a245fdd0301245fdd06380001"字符串已经实现了序列化接口。
                 * 此方法返回类型为Object,也就是对象,然后我们再强行转换为需要加载的对象就可以了。
                    如果数据不存在,则返回null
                 * 执行此方法时立即发出查询SQL语句。加载User对象。
                 */
                User user = (User)session.get(User.class, "4028818a245fdd0301245fdd06380001");
                
                //数据加载完后的状态为persistent状态。数据将与数据库同步。
                System.out.println("user.name=" + user.getName());
                
                //因为此的user为persistent状态,所以数据库进行同步为龙哥。
                user.setName("龙哥");
                
                session.getTransaction().commit();
            } catch (HibernateException e) {
                e.printStackTrace();
                session.getTransaction().rollback();
            } finally{
                if (session != null){
                    if (session.isOpen()){
                        session.close();
                    }
                }

    二、 Object Session.load(Class arg0, Serializable arg1) throws HibernateException

        * arg0:需要加载对象的类,例如:User.class

        * arg1:查询条件(实现了序列化接口的对象):例"4028818a245fdd0301245fdd06380001"字符串已经实现了序列化接口。

        * 此方法返回类型为Object,但返回的是代理对象。

        * 执行此方法时不会立即发出查询SQL语句。只有在使用对象时,它才发出查询SQL语句,加载对象

        * 因为load方法实现了lazy(称为延迟加载、赖加载)

        * 延迟加载:只有真正使用这个对象的时候,才加载(才发出SQL语句)

        * hibernate延迟加载实现原理是代理方式。

        * 采用load()方法加载数据,如果数据库中没有相应的记录,则会抛出异常对象不找到(org.hibernate.ObjectNotFoundException)

    try {
    
            session = sf.openSession();
            session.beginTransaction();
             User user = (User)session.load(User.class, "4028818a245fdd0301245fdd06380001");      
            //只有在使用对象时,它才发出查询SQL语句,加载对象。
            System.out.println("user.name=" + user.getName());      
            //因为此的user为persistent状态,所以数据库进行同步为龙哥。
            user.setName("发哥");       
            session.getTransaction().commit();
        } catch (HibernateException e) {
            e.printStackTrace();
            session.getTransaction().rollback();
        } finally{
                if (session != null){
                    if (session.isOpen()){
                        session.close();
                    }
                }
        }      

    Hibernate两种加载数据方式的区别:

        get()方法默认不支持lazy(延迟加载)功能,而load支持延迟加载

        get()方法在查询不到数据时,返回null,而load因为支持延迟加载,只有在使用对象时才加载,所以如果数据库中不在数据load会抛出异常(org.hibernate.ObjectNotFoundException)。

       

        get()和load()只根据主键查询,不能根据其它字段查询,如果想根据非主键查询,可以使用HQL

    hibernate更新数据:

    建立使用hibernate进行更新数据时,先加载数据,然后再修改后更新。

    否则一些字段可以会被null替换。

    try {
    
                session = sf.openSession();
    
                session.beginTransaction();
     
                User user = new User();
    
                user.setId("4028818a245fdd0301245fdd06380001");
    
                user.setName("wjt276");
    
                //Transient状态
    
             /*
    
              * 目前这样更新,数据库记录中此条记录,除了id、name字段为设置字段,其它均为null,因为对象其它
    
              * 属性没有设置数据,因为更新数据时要先加载需要更新数据的对象,再修改更新。
    
              */
    
                session.update(user);//user为persistent状态
    
               
    
                session.getTransaction().commit();
    
            } catch (HibernateException e) {
    
                // TODO Auto-generated catch block
    
                e.printStackTrace();
    
                session.getTransaction().rollback();
    
            } finally{
    
                if (session != null){
    
                    if (session.isOpen()){
    
                        session.close();
    
                    }
    
                }
    
            }

    Hibernate删除数据对象:

        删除对象,一般先加载上来对象,然后再删除该对象。

        对象删除后,对象状态为Transistent状态。

    代码如下:

    /**
         * hibernate删除对象
    
         */
        public void testDelete1(){
            Session session = null;
            try {
    
                session = HibernateUtils.getSession();
    
                session.beginTransaction();         
                User user = (User)session.load(User.class, "4028818a245fdd0301245fdd06380001");
    
                session.delete(user);
            
                session.getTransaction().commit();
    
            } catch (HibernateException e) {
    
                e.printStackTrace();
    
                session.getTransaction().rollback();
    
            } finally{
    
                if (session != null){
    
                    if (session.isOpen()){
    
                        session.close();
    
                    }
    
                }
    
            }
    
            //transistent状态(数据库中没有配区的数据记录。)
    
        }
  • 相关阅读:
    Android驱动开发
    LCD控制器时序参数的确定(基于TFT LCD: KD50G9-40NM-A3)
    Delphi IDHTTP用法详解
    Delphi开发Android的几个注意
    Delphi 调试连接 任意Android手机/平板/盒子
    Delphi XE10在 Android下调用静态库a文件
    Delphi的FIFO实现
    Delphi获取Android下GPS的NMEA 0183数据
    【CJOJ1603】【洛谷1220】关路灯
    【洛谷2986】【USACO10MAR】伟大的奶牛聚集
  • 原文地址:https://www.cnblogs.com/crazylqy/p/4076348.html
Copyright © 2020-2023  润新知