zoukankan      html  css  js  c++  java
  • [原创]java WEB学习笔记94:Hibernate学习之路---session 的管理,Session 对象的生命周期与本地线程绑定

    本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用

    内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系。

    本人互联网技术爱好者,互联网技术发烧友

    微博:伊直都在0221

    QQ:951226918

    -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

    1.管理 Session

      1)Hibernate 自身提供了三种管理 Session 对象的方法

        ① Session 对象的生命周期与本地线程绑定

        ② Session 对象的生命周期与 JTA 事务绑定

        ③ Hibernate 委托程序管理 Session 对象的生命周期

      2)在 Hibernate 的配置文件中,hibernate.current_session_context_class 属性用于指定 Session 管理方式, 可选值包括

        ① thread: Session 对象的生命周期与本地线程绑定

        ② jta*: Session 对象的生命周期与 JTA 事务绑定

        ③ managed: Hibernate 委托程序来管理 Session 对象的生命周期

    2.Session 对象的生命周期与本地线程绑定

      1)如果把 Hibernate 配置文件的 hibernate.current_session_context_class 属性值设为 thread, Hibernate 就会按照与本地线程绑定的方式来管理 Session

      2)Hibernate 按一下规则把 Session 与本地线程绑定

        ① 当一个线程(threadA)第一次调用 SessionFactory 对象的 getCurrentSession() 方法时, 该方法会创建一个新的 Session(sessionA) 对象, 把该对象与 threadA 绑定, 并将 sessionA 返回

          ② 当 threadA 再次调用 SessionFactory 对象的 getCurrentSession() 方法时, 该方法将返回 sessionA 对象

        ③ 当 threadA 提交 sessionA 对象关联的事务时, Hibernate 会自动flush sessionA 对象的缓存, 然后提交事务, 关闭 sessionA 对象. 当 threadA 撤销 sessionA 对象关联的事务时, 也会自动关闭 sessionA 对象

        ④ 若 threadA 再次调用 SessionFactory 对象的 getCurrentSession() 方法时, 该方法会又创建一个新的 Session(sessionB) 对象, 把该对象与 threadA 绑定, 并将 sessionB 返回

    通过单例模式创建一个HibernateUtils 工具类

     1 package com.jason.hibernate.dao;
     2 
     3 import org.hibernate.Session;
     4 import org.hibernate.SessionFactory;
     5 import org.hibernate.cfg.Configuration;
     6 import org.hibernate.service.ServiceRegistry;
     7 import org.hibernate.service.ServiceRegistryBuilder;
     8 
     9 public class HibernateUtils {
    10 
    11     private HibernateUtils(){}
    12     
    13     private static HibernateUtils instance = new HibernateUtils();
    14     
    15     private SessionFactory sessionFactory;
    16     
    17     public static HibernateUtils getInstance(){
    18         return instance;
    19     }
    20     
    21     private SessionFactory getsSessionFactory(){
    22         
    23         if(sessionFactory == null){
    24             Configuration configuration = new Configuration().configure();
    25             ServiceRegistry serviceRegistry = new ServiceRegistryBuilder()
    26                     .applySettings(configuration.getProperties())
    27                     .buildServiceRegistry();
    28 
    29             sessionFactory = configuration.buildSessionFactory(serviceRegistry);
    30         }
    31         
    32         return sessionFactory;
    33     }
    34     
    35     
    36     public Session getsSession(){
    37         return getsSessionFactory().getCurrentSession();
    38     }
    39     
    40     
    41     
    42     
    43 }

    3.批量处理数据

      1)批量处理数据是指在一个事务中处理大量数据.

      2)在应用层进行批量操作, 主要有以下方式:   通过 Session; 通过 HQL; 通过 StatelessSession; 通过 JDBC API;

      

      3)通过 Session 来进行批量操作

        ① Session 的 save() 及 update() 方法都会把处理的对象存放在自己的缓存中. 如果通过一个 Session 对象来处理大量持久化对象, 应该及时从缓存中清空已经处理完毕并且不会再访问的对象. 具体的做法是在处理完一个对象或小批量对象后, 立即调用 flush() 方法刷新缓存, 然后在调用 clear() 方法清空缓存

      

        ② 通过 Session 来进行处理操作会受到以下约束

         > 需要在 Hibernate 配置文件中设置 JDBC 单次批量处理的数目, 应保证每次向数据库发送的批量的 SQL 语句数目与 batch_size 属性一致

         > 若对象采用 “identity” 标识符生成器, 则 Hibernate 无法在 JDBC 层进行批量插入操作

         >  进行批量操作时, 建议关闭 Hibernate 的二级缓存

        ③ 批量更新: 在进行批量更新时, 如果一下子把所有对象都加载到 Session 缓存, 然后再缓存中一一更新, 显然是不可取的;

         使用可滚动的结果集 org.hibernate.ScrollableResults, 该对象中实际上并不包含任何对象, 只包含用于在线定位记录的游标. 只有当程序遍历访问 ScrollableResults 对象的特定元素时, 它才会到数据库中加载相应的对象.

        

    4.通过 HQL 来进行批量操作:HQL 只支持 INSERT INTO … SELECT 形式的插入语句, 但不支持 INSERT INTO … VALUES 形式的插入语句. 所以使用 HQL 不能进行批量插入操作

    5.通过StatelessSession来进行批量操作:从形式上看,StatelessSession与session的用法类似

        StatelessSession与session相比,有以下区别:

        1)StatelessSession没有缓存,通过StatelessSession来加载、保存或更新后的对象处于游离状态

        2)StatelessSession不会与Hibernate的第二级缓存交互。

        3)当调用StatelessSession的save()、update()或delete()方法时,这些方法会立即执行相应的SQL语句,而不会仅计划执行一条SQL语句

        4)StatelessSession不会进行脏检查,因此修改了Customer对象属性后,还需要调用StatelessSession的update()方法来更新数据库中数据。

        5)StatelessSession不会对关联的对象进行任何级联操作。

        6)通过同一个StatelessSession对象两次加载OID为1的Customer对象,得到的两个对象内存地址不同。

        7)StatelessSession所做的操作可以被Interceptor拦截器捕获到,但是会被Hibernate的事件处理系统忽略掉。

  • 相关阅读:
    [动态规划]保存子问题的结果
    [字符串]第一个不重复的字符
    [抽象建模问题]扑克牌的顺子判断
    [算法]处理连续小段问题
    [动态规划]最长回文子串
    违法
    TCP的拥塞控制
    SpringBank 开发日志 一种简单的拦截器设计实现
    SPFILEOPENBANKDB.ORA 手动编辑产生问题
    springbank 开发日志 springbank是如何执行一个handler的requestMapping对应的方法的
  • 原文地址:https://www.cnblogs.com/jasonHome/p/5937028.html
Copyright © 2011-2022 走看看