• Hibernate框架后续


    持久化对象的唯一标识OID

    1:我们都知道,在java中按照内存地址来区分同一个类的不同对象

           而关系数据库按照主键来区分一条记录

    在Hibernate中使用OID来建立内存中的对象和数据库中记录对应的关系

    ????什么是OID

    答:OID就是持久化类(Student)与数据库主键表对应属性,用唯一来区分持久化对象

    2:为何要使用包装类呢(如Integer)?

    因为包装类Integer可以存储null值

    我们来模仿这样的一个场景:“一个学生成绩为0,无法区分是参加了考试考取了0分,还是没有成绩。如果使用包装类,数据库就会存入null,证明该学生没有参加考试"

    二:主键生成策略

    increment

    identity

    sequence:在DB端生成序列

    native:在DB端生成序列

    uuid:在应用程序端生成

    assigned:在应用程序端生成

    在小配置文件hbm.xml中进行如下配置

    当我们使用sequence的时候,仅仅只有oracle支持,当我们使用active的时候,无论是mysql还是oracle,都可以生成序列。

    native)

    采用数据库支持自增策略, mysql就用identity 、oracle就用sequence

    策略1) ---> 策略4) 要求数据库主键必须为数字 ,因为只有数字才能自增 

    uuid)生成一个32位的16进制数,在java应用端产生,同样不需要程序员手动添加

    复合主键,是一种特殊 assigned类型 自然主键 (通常需要手动指定),PO类必须实现Serializable接口

    三:hibernate中java对象的三种状态

    1:瞬时状态

    2:持久状态

    3:游离状态

    详见下图:

    赠图一张!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

    四:关于load()方法和get()方法的区别

    Session.load/get方法均可以根据指定的实体类和id从数据库读取记录,并返回与之对应的实体对象。

    其区别在于:

    如果未能发现符合条件的记录,get方法返回null,而load方法会抛出一个ObjectNotFoundException。

    Load方法可返回实体的代理类实例,而get方法永远直接返回实体类。

    举个例子,代码如下:

    复制代码
        public static void getTest()
        {
         Student stu=(Student)Hibernate_until.getSession().get(Student.class, 2);
        }
        public static void getload()
        {
         Student stu=(Student)Hibernate_until.getSession().load(Student.class, 2);
         System.out.println(stu.getClass());
         System.out.println(stu);
        }
    复制代码

    当执行getload()时进入断点调试,当没有启用stu对象的时候,默认geload()方法的initialized属性是false;target默认是null值。

    当点击stu对象时,这两种属性激活,initialized属性变为true,target则为代理对象存入相应的数据。

       与get()的区别:
       1:在立即加载对象(当hibernate在从数据库中取得数据组装好一个对象后
       会立即再从数据库取得数据此对象所关联的对象)时,如果对象存在,
       load()和get()方法没有区别,都可以取得已初始化的对象;但如果当对
       象不存在且是立即加载时,使用get()方法则返回null,而使用load()则
       抛出一个异常。因此使用load()方法时,要确认查询的主键ID一定是存在
       的,从这一点讲它没有get方便!

      2:在延迟加载对象(Hibernate从数据库中取得数据组装好一个对象后,
      不会立即再从数据库取得数据组装此对象所关联的对象,而是等到需要时,
      都会从数据库取得数据组装此对象关联的对象)时,get()方法仍然使用
      立即加载的方式发送SQL语句,并得到已初始化的对象,而load()方法则
      根本不发送SQL语句,它返回一个代理对象,直到这个对象被访问时才被
      初始化。

    五:脏检查和刷新缓存机制

    赠图一张:

    解析:当事务提交时,hibernate会对session中的持久状态的对象进行检测,判断对象中的数据是否发生了改变。

    当内存中的数据发生改变时,就要将数据更新到db端

    如何脏检查:

    当一个实体类对象存入到session中时,session会为该对象的值类型生成一份快照,当session刷新缓存的时候首先进行脏检查,即比较对象中的数据和快照,来判断对象中的数据是否发生了改变,如果发生了变化,session会根据脏对象的最新数据来更新db端的数据

    那么,session会在什么时间点来刷新缓存呢

    1)事务的commit

    2)session.flush()方法

  • 相关阅读:
    常见网络攻击手段原理分析
    admins.py总结比较,转
    django的表与表之间的关系详细讲解
    django中的@login_required
    安装指定版本的第三方库
    在django中使用logging
    django的manytomany总结
    manyToManyField理解和用法
    django的多对一,一对一,多对多关系
    python 的os的总结
  • 原文地址:https://www.cnblogs.com/1And0/p/5821771.html
Copyright © 2020-2023  润新知