zoukankan      html  css  js  c++  java
  • Hibernate持久化

    一、主键生成策略

      1)主键分类:1.自然主键:主键本身就是表中的某一个字段,实体中的一个具体属性,对象本身唯一的特性。

              例如:创建一个学生,把其身份证号设为主键

             2.代理主键:本身不是表中的一个必须的字段,

              例如:创建一个学生,设置sid为主键。

               实际开发中,尽量使用代理主键。

      2)主键生成策略:在使用代理主键时,尽量自动生成主键,不让用户手动输入。

               在hibernate中,为了减少程序的编写,内部提供了多种主键生成策略

              1.increment:

                1.1自动增长策略:是适用于整型(long , short,int )

                1.2原理:首先发送一条语句,select max(id) from 表,然后加一。即查询最大id,然后进行加1。

                1.3在单线程中使用,不要在多线程中使用。

              2.identify

                2.1自动增长:是适用于整型(long , short,int )

                2.2原理:使用的是数据库底层的增长策略,适用于有自动增长的数据库,如mysql。

                2.3多线程安全。

              3.uuid 

                3.1适用于字符串类型的主键,使用hibernate中随机生成字符的主键。

              4.native

                4.1 自动增长,会根据所采用的数据库类型,自动变成identify(masql)或sequence(oracle)

              5.assigned

                 hibernate不会帮你管理主键,需要手动调用,或通过程序生成。

              一般开发中使用uuid与native。

    二、持久化

       1)什么是持久化:将内存中的一个对象存储到数据库中的过程。

       2)什么是持久化类:一个java类与数据库类建立的映射关系(java类+映射文件)

       3)持久化类编写规则:

          1.对持久化类提供一个无参的构造方法(一个类,如果没有构造方法,默认存在一个无参构造方法,如果重写了,则不会生成无参构造方法)。

            因为其内部通过反射创建对象,没有构造方法就无法创建对象。

          2.对内部私有的字段,必须提供get,set方法。(否则,hibernate无法获取对象的值)

          3.持久化类中提供一个oid与数据库中的主键对应。

          4.持久化类中的属性尽量使用包装类型(包装类型默认值是null,基本数据类型为数字)

          5.持久化类不能使用final来修饰。

    三、持久化类的划分

      1)hibernate为了更好的管理持久化类,将持久化类分为三种状态。

        1.瞬时态:没有唯一的oid,没有被session管理。

        2.持久态:有唯一oid,被session管理。

        3.游离态/托管态/离线态:有唯一oid,但是没有被session管理

      2)三种状态划分:

         1.瞬时态:刚被new出来,还没有设置id,没有被session管理。

         2.持久态:已经有id了,调用session方法,把对象给session才被session管理。

              当对象处于持久态时,可以自动更新数据库。

         3.游离态:把session关闭时,对象处于游离态。

       @Test
        public void test3(){
            /*直接创建对象修改:如果没有指定其他字段,会把其他字段设为null*/
            Session session = HibernateUtil.openSession();
            Transaction transaction = session.beginTransaction();
            //更新操作
            customer customer = new customer();//瞬时态
            customer.setCust_id(1L);
            customer.setCust_name("wzh");
            session.update(customer);//持久态
            customer.setCust_name("123");//处于持久态的对象具有更新数据库的能力
            transaction.commit();
            session.close();//游离态
            HibernateUtil.sessionFactory.close();
        }

          三种状态相互转换:

    四、一级缓存

      1)什么是缓存:是一种优化方式,将数据存入内存中,使用的时候,直接从缓存中获取,不用直接到存储源(数据库)中获取。

          一级缓存:hibernate自带

          二级缓存:现在一般使用radis,不使用其自带的。

      2) 一级缓存:1.session级别的缓存,

             2.声明周期与session一致,一级缓存由session中的一系列集合构成。

             3.是自带的,不可卸载。(二级缓存是sessionFactory级别的)

      3)一级缓存的特点:查询更新是先检查缓存中有没有相应数据,有则不会查询数据库,没有就查询数据库,并把查询到的记录同步到缓存。当调用session.close方法时,缓存清空。

      4)一级缓存内部结构:

         快照区:使用id进行查询数据库时,将查询的结果放到session的一级一级缓存中,同时复制一份数据,放置到session的快照中。

             当使用tr.commit()时,同时清理session的一级缓存(flush)

             当清理session一级缓存时,会使用Oid判断一级缓存中的对象与快照中的对象进行比较,如果两个对象中,对象属性发生变化,则执行update语句,此时

             更新数据库,更新成一级缓存中的数据,如果两个对象中属性一致,此时不执行update操作。

              (存入数据时,存入数据库的同时存入缓存区与快照区,更新时,只是更新缓存区,提交事务时,对比快照区与缓存区对象是否一样,不一样,说明已经进行了更新操作

               这时候才发送一条更新的sql给数据库,进行更新)

              目的:确保数据库中的数据一致。

    五、事务管理

      1)事务:逻辑上的一组操作,要么都完成,要么都失败。

      2)事务特性:原子性,隔离性,一致性,持久性。

      3)事务的隔离级别

      4)在hibernate中设置事务的隔离级别:在核心配置文件中hibernate.cfg.xml中,设置

              <property name="hibernate.connection.isolation">4</property>

          通过数字设置隔离级别。

      5)事务的开启一般在service层开启。开启的过程需要保证与外部dao中用的时同一个连接对象(session),开发中,通常将session绑定到ThreadLocal中。 

        事务业务层连接:

          1.为什么要在业务层使用事务:业务层可以调用多个dao层的操作

          2.在业务层使用事务时,必须保证获取事务的连接和dao层操作的连接是同一个,否则,就管理不了对应的操作。

          3.使用jdbc中事务业务层的处理方法:

              3.1 向下传递:开始在业务层先创建好一个连接,传给dao层,让dao层使用这个连接执行操作。

              3.2 使用ThreadLocal对象:在service方法当中把创建的连接绑定到对应的ThreadLocal当中,在dao方法中,通过当前线程获取连接对象。

          4.hibernate中的处理方法:

              4.1Hibernate框架内部已经绑定好了ThreadLocal,在SessionFactory中,提供了一个方法,getCurrentSession()方法,获取当前线程中的session。

                但是此方法默认不可使用。

              4.2需要在核心配置文件中配置

              <property name="current_session_context_class">thread</property>
              创建一个session绑定到当前线程。
               4.3通过它来操作时,不需要close,执行结束会自动close
        在utils中:
        public static Session getCurrentSession(){
            //从ThreadLocal中获取的session
            Session session =sessionFactory.getCurrentSession();
            return  session;
        }

        test中:

      @Test
        public void test3(){
            /*直接创建对象修改:如果没有指定其他字段,会把其他字段设为null*/
            Session session = HibernateUtil.getCurrentSession();
            Transaction transaction = session.beginTransaction();
            //更新操作
            customer customer = new customer();//瞬时态
            customer.setCust_id(3L);
            customer.setCust_name("xxl");
            session.update(customer);//持久态
            //customer.setCust_name("123");//处于持久态的对象具有更新数据库的能力
            transaction.commit();
            //session.close();//游离态
            //HibernateUtil.sessionFactory.close();
        }
    
    
  • 相关阅读:
    hdu 2222 Keywords Search
    Meet and Greet
    hdu 4673
    hdu 4768
    hdu 4747 Mex
    uva 1513 Movie collection
    uva 12299 RMQ with Shifts
    uva 11732 strcmp() Anyone?
    uva 1401
    hdu 1251 统计难题
  • 原文地址:https://www.cnblogs.com/UalBlog/p/10601770.html
Copyright © 2011-2022 走看看