zoukankan      html  css  js  c++  java
  • HIbernate学习笔记(二) hibernate对象的三种状态与核心开发接口

    1、在hibernate中持久化对象有三个状态,这个面试时可能会问到:
     (1)transient瞬时态:在数据库中没有与之匹配的数据,一般就是只new出了这个对象,并且在session缓存中也没有即此对象没有纳入session的管理,此状态的对象不能直接存入数据库(会抛出TransientObjectException)。
     (2)persistent持久态:在数据库中有与之匹配的数据,并且纳入了session的管理(一般就是执行了save、update、load、 get后的对象),在提交事务时(清理session缓存时)会和数据库同步更新,持久态对象才可以存入数据库。
     (3)detached游离态:在数据库中有与之匹配的数据,但没有纳入session缓存的管理。

      三种对象的区别:

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

                                内存中一个对象,没有ID,缓存中也没有

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

                                内存中有、缓存中有、数据库有(ID)

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

    内存有、缓存没有、数据库有(ID)

     

    2、 核心开发接口Configuration(AnnotationConfiguration)

    作用:进行配置信息的管理

    目标:用来产生SessionFactory

    可以在configure方法中指定hibernate配置文件,默认(不指定)时在classpath下加载hibernate.cfg.xml文件

    加载默认的hibernate的配置文件

    sessionFactory = newAnnotationConfiguration().configure().buildSessionFactory();

    加载指定hibernate的配置文件

    sessionFactory=newnnotationConfiguration().configure("hibernate.xml").buildSessionFactory();

    只需要关注一个方法:buildSessionFactory();

    3、核心开发接口 SessionFactory

    作用:主要用于产生Session的工厂(数据库连接池)

    当它产生一个Session时,会从数据库连接池取出一个连接,交给这个Session

    Session session = sessionFactory.getCurrentSession();

             并且可以通过这个Session取出这个连接

             关注两个方法:

             getCurrentSession():表示当前环境没有Session时,则创建一个,否则不用创建

             openSession():     表示创建一个Session(3.0以后不常用),使用后需要关闭这个Session

             两方法的区别:

               ①、openSession永远是每次都打开一个新的Session,而getCurrentSession不是,是从上下文找、只有当前没有Session时,才创建一个新的Session

               ②、OpenSession需要手动close,getCurrentSession不需要手动close,事务提交自动close

               ③、getCurrentSession界定事务边界

    上下文:

    所指的上下文是指hibernate配置文件(hibernate.cfg.xml)中的“current_session_context_class”所指的值:(可取值:jta|thread|managed|custom.Class)

    <property name="current_session_context_class">thread</property>

             常用的是:①、thread:是从上下文找、只有当前没有Session时,才创建一个新的Session,主要从数据界定事务

                  ②、jta:主要从分布式界定事务,运行时需要Application Server来支持(Tomcat不支持)

                 ③、managed:不常用

        ④、custom.Class:不常用

         

    4、核心开发接口 Session

      1)管理一个数据库的任务单元

      2)save();

      session.save(Object)

      session的save方法是向数据库中保存一个对象,这个方法产生对象的三种状态

        3)delete() 

      session.delete(Object)

         Object对象需要有ID

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

      4)load()

    格式: Session.load(Class arg0,Serializable arg1) throws HibernateException

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

        *arg1:查询条件(实现了序列化接口的对象):例"4028818a245fdd0301245fdd06380001"字符串已经实现了序列化接口。如果是数值类类型,则hibernate会自动使用包装类,例如 1

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

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

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

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

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

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

      5)Get()     

      格式:Session.get(Class arg0,Serializable arg1)方法

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

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

    例"4028818a245fdd0301245fdd06380001"字符串已经实现了序列化接口。如果是基数类型,则hibernate会自动转换成包装类,如 1

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

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

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

      6)load()与get()区别

      ①、 不存在对应记录时表现不一样;

      ②、 load返回的是代理对象,等到真正使用对象的内容时才发出sql语句,这样就要求在第一次使用对象时,要求session处于open状态,否则出错

      ③、 get直接从数据库加载,不会延迟加载

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

      7)update()

    ①        、用来更新detached对象,更新完成后转为为persistent状态(默认更新全部字段)

    ②        更新transient对象会报错(没有ID)

    ③        更新自己设定ID的transient对象可以(默认更新全部字段)

    ④        persistent状态的对象,只要设定字段不同的值,在session提交时,会自动更新(默认更新全部字段)

    ⑤        更新部分更新的字段(更改了哪个字段就更新哪个字段的内容)

    a)       方法1:update/updatable属性

     xml:设定<property>标签的update属性,设置在更新时是否参数更新

    <property name="name" update="false"/>

    注意:update可取值为true(默认):参与更新;false:更新时不参与更新

    annotateon:设定@Column的updatable属性值,true参与更新,false:不参与更新

        @Column(updatable=false)

        public String getTitle(){return title;}

    注意:此种方法很少用,因为它不灵活

    b)       方法二:dynamic-update属性

    注意:此方法目前只适合xml方式,JAP1.0annotation没有对应的

    在实体类的映射文件中的<class>标签中,使用dynamic-update属性,true:表示修改了哪个字段就更新哪个字段,其它字段不更新,但要求是同一个session(不能跨session),如果跨了session同样会更新所有的字段内容。

      8)clear()

    清除session缓存

    无论是load还是get,都会首先查找缓存(一级缓存,也叫session级缓存),如果没有,才会去数据库查找,调用clear()方法可以强制清除session缓存

        Session session= sessionFactory.getCurrentSession();

        session.beginTransaction();

        Teacher t =(Teacher)session.load(Teacher.class, 1);

        System.out.println(t.getName());       

        session.clear();       

        Teacher t2 =(Teacher)session.load(Teacher.class, 1);

        System.out.println(t2.getName());

        session.getTransaction().commit();

    注意:这样就会发出两条SELECT语句,如果把session.clear()去除,则只会发出一条SELECT语句,因为第二次load时,是使用session缓存中ID为1的对象,而这个对象已经在第一次load到缓存中 了。

      9)flush()

    在hibernate中也存在flush这个功能,在默认的情况下session.commit()之前时,其实执行了一个flush命令。

    Session.flush功能:

    n         清理缓存;

    n         执行sql(确定是执行SQL语句(确定生成update、insert、delete语句等),然后执行SQL语句。)

    Session在什么情况下执行flush:

    ①         默认在事务提交时执行;

    注意:flush时,可以自己设定,使用session.setFlushMode(FlushMode)来指定。

      session.setFlushMode(FlushMode);

    FlushMode的枚举值:

    l     FlushMode.ALWAYS:任务一条SQL语句,都会flush一次

    l     FlushMode.AUTO  :自动flush(默认)

    l     FlushMode.COMMIT: 只有在commit时才flush

    l     FlushMode.MANUAL:手动flush。

    l    FlushMode.NEVER :永远不flush  此选项在性能优化时可能用,比如session取数据为只读时用,这样就  

    不需要与数据库同步了

            注意:设置flush模式时,需要在session开启事务之前设置。

    ②        可以显示的调用flush;

    ③        在执行查询前,如:iterate.

    注:如果主键生成策略是uuid等不是由数据库生成的,则session.save()时并不会发出SQL语句,只有flush时才会发出SQL语句,但如果主键生成策略是native由数据库生成的,则session.save的同时就发出SQL语句。

  • 相关阅读:
    进程
    并发编程小结
    操作系统发展史
    基于socketsever实现并发的socket编程
    UDP套接字
    粘包问题及解决
    socket套接字编程
    TCP协议与三次握手四次挥手
    OSI七层协议
    互联网的组成
  • 原文地址:https://www.cnblogs.com/hustfly/p/3434388.html
Copyright © 2011-2022 走看看