zoukankan      html  css  js  c++  java
  • Hibernate系列教程之一(Hibernate结构)

    @author:WMsteve
    @Email:weisteve@yeah.net
    @Time:2012年1月1日20:51:33
     

    作者认为学习计算机的相关知识,需要通过下面几种步骤,不仅能从本质上了解它,同时也能更灵活的掌握:

    1.         了解此项技术的产生的背景(传统的做法如何,为什么要出现这项技术,试图去解决什么问题)

    2.         此项技术采用的思想(总体框架,整体分几个模块或者分几层)

    3.         每层对应传统方法的哪个步骤或者对应传统方法的是哪个部分

    4.         技术对传统方式的优缺点(自己总结)

    下面咱们来看下hibernate的工作原理,也算是对自己之前掌握的只是的一种总结。

    看下图:

    传统的数据库操作,一般利用SQL语句通过JDBC或者ODBC驱动DBMS完成数据的CRUB,业务数据的维持完全交由了程序来完成。面向关系的数据库操作已经不太能跟软件开发中的OO思想相协调,一定程度上来说无法满足OO开发的需要。

    同时SQLDBMS来说不是线程安全的,所以在每打开一次连接,进行相应操作后应立刻关闭连接。在大数据量的访问时,需要手工建立、管理缓冲池来满足系统高并发的需求。对数据库开发人员来说无疑是一种高要求。

    Hibernate是为了解决上述问题应运而生的技术,负责数据持久化的工作。

    它不但能够通过配置映射文件屏蔽对数据源中表的操作,同时会话层Session负责提供了连接池Pool,对大并发度的数据库操作进行了缓冲处理。其映射文件对应的类与数据库的表是一一对应关系,与软件开发的思想结合的更好更密切。

    通过上图可以看出Hibernate框架大致包括了四个部分:

    x  Configuration

    x  SessionFactory

    x  Session会话

    x  事务处理

    Hibernate在运行过程中整个工作流程描述如下:

    Hiberante启动初始化,读取hibernate.cfg.xml(文件名不一定是hibernate.cfg.xml,只不过默认是hiberante.cfg.xml,如若更改为hibernate_common.xml,那么在HibernateSessionFactory中需要更改默认的配置文件名,默认文件名在HibernateSessionFactory中表现为一个常量)。

    private static String CONFIG_FILE_LOCATION = "/hibernate_common.xml";

    首先让我们看下Hibernate建议给我们的HibernateSessionFactory内容:

    package com.dj.hibernate;
     
    import org.hibernate.HibernateException;
    import org.hibernate.Session;
    import org.hibernate.cfg.Configuration;
    import org.hibernate.cfg.AnnotationConfiguration;
     
    /**
     * Configures and provides access to Hibernate sessions, tied to the
     * current thread of execution.  Follows the Thread Local Session
     * pattern, see {@link http://hibernate.org/42.html }.
     */

    public class HibernateSessionFactory {
     
        /** 
         * Location of hibernate.cfg.xml file.
         * Location should be on the classpath as Hibernate uses  
         * #resourceAsStream style lookup for its configuration file. 
         * The default classpath location of the hibernate config file is 
         * in the default package. Use #setConfigFile() to update 
         * the location of the configuration file for the current session.   
         */

        private static String CONFIG_FILE_LOCATION = "/hibernate_common.xml";
             private static final ThreadLocal<Session> threadLocal = new ThreadLocal<Session>();
        private  static Configuration configuration = new AnnotationConfiguration();
        private static org.hibernate.SessionFactory sessionFactory;
        private static String configFile = CONFIG_FILE_LOCATION;
     
             static {
                 try {
                                configuration.configure(configFile);
                                sessionFactory = configuration.buildSessionFactory();
                       } catch (Exception e) {
                                System.err
                                                   .println("%%%% Error Creating SessionFactory %%%%");
                                e.printStackTrace();
                       }
        }
        private HibernateSessionFactory() {
        }
             
             /**
         * Returns the ThreadLocal Session instance.  Lazy initialize
         * the <code>SessionFactory</code> if needed.
         *
         *  @return Session
         *  @throws HibernateException
         */

        public static Session getSession() throws HibernateException {
            Session session = (Session) threadLocal.get();
     
                       if (session == null || !session.isOpen()) {
                                if (sessionFactory == null) {
                                         rebuildSessionFactory();
                                }
                                session = (sessionFactory != null) ? sessionFactory.openSession()
                                                   : null;
                                threadLocal.set(session);
                       }
     
            return session;
        }
     
             /**
         *  Rebuild hibernate session factory
         *
         */

             public static void rebuildSessionFactory() {
                       try {
                                configuration.configure(configFile);
                                sessionFactory = configuration.buildSessionFactory();
                       } catch (Exception e) {
                                System.err
                                                   .println("%%%% Error Creating SessionFactory %%%%");
                                e.printStackTrace();
                       }
             }
     
             /**
         *  Close the single hibernate session instance.
         *
         *  @throws HibernateException
         */

        public static void closeSession() throws HibernateException {
            Session session = (Session) threadLocal.get();
            threadLocal.set(null);
     
            if (session != null) {
                session.close();
            }
        }
     
             /**
         *  return session factory
         *
         */

             public static org.hibernate.SessionFactory getSessionFactory() {
                       return sessionFactory;
             }
     
             /**
         *  return session factory
         *
         *     session factory will be rebuilded in the next call
         */

             public static void setConfigFile(String configFile) {
                       HibernateSessionFactory.configFile = configFile;
                       sessionFactory = null;
             }
     
             /**
         *  return hibernate configuration
         *
         */

             public static Configuration getConfiguration() {
                       return configuration;
             }
    }
    通过全局静态变量,运行与单例模式状态下。需要进行数据库操作时,需要通过HibernateSessionFactory取得单例的SessionFactory,工厂的建立是通过读取CONFIG_FILE_LOCATION常量的配置文件来确定运行状态,以及与数据源的连接参数,进而产生sessionFactory

    当有需要通过hiberante进行与数据库的交互时,此时sessionFactory生产一个session进行与数据源的会话。

    Tips:对数据源的操作是通过sessionFactory生成一个一个session(看明白前面,是不是可以想象出连接池的建立在这种模式下很容易就能实现?)。

    前面说过JDBCDBMS的操作不是线程安全的,hibernate也是如此。所以hibernate中对数据源的每次操作都需要申请一个session,可以理解为一次打开数据源的连接,一次操作结束,session要立刻关闭,因为Hibernate中也不是线程间安全的。

    至此,数据源连接已经完成,那么后续需要讲内存中的数据写入数据库系统,开启一个事务,然后进行数据库操作,成功执行,事务结束,同时关闭session

    在这章节里面,咱们不去讨论hbm文件映射,也不去讨论映射文件中类型的关系,更不去看主键的生成策略。

    仅仅告诉梳理了hibernate的操作流程和大致步骤。

    详细的后续章节会介绍。





    作者:W.M.steve
    出处:http://www.cnblogs.com/weisteve/
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
  • 相关阅读:
    java01 java基础知识
    01 开发准备 启动PHP服务与环境配置
    Axure 9.0 使用教程2-函数分类
    Axure 9.0 使用教程1-软件概述
    Python 字符串 列表 元组 字典 集合学习总结
    Python 函数定义 调用 迭代器 生成器 递归和推导式
    Python习题
    Python 条件 循环 及其他语句
    Python 字典
    Python 字符串
  • 原文地址:https://www.cnblogs.com/weisteve/p/2309750.html
Copyright © 2011-2022 走看看