Hibernate学习笔记

      题记: 不管是学习一门新的语言还是一门新的技术或者新的框架学习的时候兴致勃勃,但是学习完成之后总是有一种茫然无知的感觉。这种感觉是由于什么导致的呢?只有在不断的探索中去发现问题然后解决问题。

    既然要学习一个新的事物我想最基本的需要明白自己为什么学习这个东西,这个东西有什么价值值得你去学习,学习之后你有什么收获。因此,学习Hibernate我想搞懂以下几个问题:

一、 什么是Hinernate?

二、 为什么要学习并且使用Hibernate(Hibernate可以帮助我解决什么样的问题)?

三、 Hibernate的优点和不足分别是什么?

四、如何使用Hibernate?

五、如何在项目中使用Hibernate?以及如何优化Hibernate的使用?

六、总结。

    以下的篇幅将会用一个月的时间来对Hibernate的学习进行总结。

一、 什么是Hinernate?

    Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,使得Java程序员可以随心所欲的使用对象编程思维来操纵数据库。 Hibernate可以应用在任何使用JDBC的场合,既可以在Java的客户端程序使用,也可以在Servlet/JSP的Web应用中使用,最具革命意义的是,Hibernate可以在应用EJB的J2EE架构中取代CMP,完成数据持久化的重任。

   扩展: 1、Hibernate的官方网站:http://hibernate.org

二、 为什么要学习并且使用Hibernate(Hibernate可以帮助我解决什么样的问题)?

    这个问题可以转化为这样的描述: 因为Hibernate的出现主要是为了解决JDBC的困扰(那么JDBC的困扰是什么呢?)

    Hibernate原理,与JDBC比较:

    

    Hibernate是一个持久化框架。

   那什么是持久化呢?我们先来理解下瞬间状态,保存在内存中的程序数据在程序退出后数据就消失了,这就称之为瞬间状态。而持久状态是我们保存在了磁盘上,

就成为程序数据的持久化状态。持久化就是将程序数据在瞬间状态和持久状态之间装换的机制。用JDBC完成数据在持久和瞬间状态的转换。  什么是JDBC呢?java data base connectivity,java数据库连接。是一种执行SQL语句的Java API。

    JDBC和Hibernate的比较:  

  相同点:

  1.都是JAVA的数据库操作中间件。

  2.两者对于数据库进行直接操作的对象都不是线程安全的,都需要及时关闭。

  3.两者都可以对数据库的更新操作进行显式的事物处理。  

  不同点:

  1.使用的SQL语言不同,JDBC是基于关系型数据库的标准SQL语言,Hibernate使用的是HQL(Hibernate query language)语言。

  2.操作的对象不同:JDBC操作的是数据,将数据通过SQL语句直接传送到数据库中执行,而Hibernate操作的是持久化对象,由底层持久化对象的数据更新到数据库中。

  3.数据状态不同:JDBC操作的数据时“瞬时"的,变量值无法与数据库中的值保持一致,而Hibernate操作的数据时刻持久的,就是持久化对象的数据属性的值时可以跟数据库中的值保持一致的。

  ORM(对象----关系映射):也就是对象数据到关系型数据的映射。类中的属性映射到了数据库中对应的字段中。表现层中数据传给业务逻辑层,有了对象数据,然后再通过持久化层成为了关系型数据。

==========================================================================================================================================================

  个人关于为什么要学习Hibernate总结以下几点:

  1、学习Hibernate的好处是,可以帮助我们在使用Java开发应用程序的过程中节省时间,使我们对数据库的操作更加简单和便捷。

  2、在使用Hibernate之后即使开发人员不会编写SQL语句也可以进行数据库的CRUD操作。因为Hibernate是一个ORM(Object/Relation Mapping)框架,它使用的是(Hibernate Query Language 简称HQL)

  3、使用Hibernate可以解决使用JDBC的一个比较繁琐的问题:不用编写大量的重复的对数据库表操作的代码,从工作量上减轻了程序员的工作负担,而且提升了软件的开发效率。但是在大型项目上使用Hibernate的时候应该慎重考虑,因为Hibernate当操作大数据量的业务的时候可能会存在效率上不如JDBC的情况,但是要看开发人员对Hibernate的了解程度和使用的熟悉程度。

  因此,Hibernate可以帮助我们解决在软件开发过程中为数据持久化的提供很大的便捷。让我们实现相同的业务逻辑,编写更少的数据库操作代码,而且思路更清晰,更直观。(说的有问题求赐教)

==========================================================================================================================================================

三、 Hibernate的优点和不足分别是什么?

   作为一个比较成熟的框架也不一定是十全十美的,在给我们带来开发便捷的同时可能也会有一些不足之处:今天就让我们一起探讨Hibernate的优点和不足。

  在探讨优缺点之前,让我们先了解一下Hibernate的好处和基本工作原理:

  

   1、使用Hibernate的好处(优点):

    ①、引入Hibernate可以使工作人员角色细化,让程序员更关心业务流程,让数据库人员更关心数据库的各种操作;

    ②、分层更清晰,耦合性更小;

    ③、通用性更强: 可以从一个数据库平台转移到另一个数据库平台。

    ④、对象话: 把关系型数据库转换成Java对象,操作更方便。

    ⑤、性能保证: Hibernate可能按照不同的数据库,处理不同的操作是用最优化的SQL语句。

    ⑥、增加了程序员的鲁棒性。

    2、 Hibernate的基本工作原理:

      Hibernate的基本工作原理是通过反射机制,将DB中的表和Java中的类进行映射。

   3、 Hibernate的不足(缺点):

        ①、对Hibernate这样的成熟框架而言的话,可能最大的缺点就是在性能方面的不足了。Hibernate是将数据库操作抽象化成ORM操作,真正的执行还得转化成                   相应的数据操作语言才可以达到数据操作的目的。因此,在给我们带来使用和操作便捷的同时,也给我们引入了性能不足的问题。

        ②、在开发一些并发不是很高,流量不是很大的网站的时候,使用Hibernate时足够满足用户和客户需求的,但是对一些高并发,大数据量和大流量的网站进                             行开发的时候就必须慎重使用Hibernate这类的ORM框架。这可能会给你日后埋下了弊端。

 四、如何使用Hibernate?

       1、Hibernate的SessionFactory编写:

        

package com.zz.util;

import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.cfg.Configuration;

/**
 * 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 final ThreadLocal<Session> threadLocal = new ThreadLocal<Session>();
    private static org.hibernate.SessionFactory sessionFactory;
    
    private static Configuration configuration = new Configuration();
    private static String CONFIG_FILE_LOCATION = "/hibernate.cfg.xml";
    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;
    }

}

      2、Hibernate各个接口的介绍:

        ①、 Configuration接口:

            

          Configuration负责管理Hibernate的配置信息。Hibernate运行时需要一些底层实现的基本信息。这些信息包括:数据库URL、数据库用户名、

       数据库用户密码、数据库JDBC驱动类、数据库dialect。用于对特定数据库提供支持,其中包含了针对特定数据库特性的实现,如Hibernate数据库类型                到特定数据库数据类型的映射等。

            使用Hibernate必须首先提供这些基础信息以完成初始化工作,为后续操作做好准备。这些属性在Hibernate配置文件hibernate.cfg.xml中加以设定,

        当调用:

            Configuration config=new Configuration().configure();

            时,Hibernate会自动在目录下搜索hibernate.cfg.xml文件,并将其读取到内存中作为后续操作的基础配置。

          ②、 SessionFactory接口:

      

            SessionFactory负责创建Session实例,可以通过Configuration实例构建SessionFactory

            Configuration config=new Configuration().configure();

            SessionFactorysessionFactory=config.buildSessionFactory();

            Configuration实例config会根据当前的数据库配置信息,构造SessionFacory实例并返回。SessionFactory一旦构造完毕,即被赋予特定的配置信息。也就是说,

            之后config的任何变更将不会影响到已经创建的SessionFactory实例sessionFactory。如果需要使用基于变更后的config实例的SessionFactory,需要从config重新构建一

            个SessionFactory实例。

            SessionFactory保存了对应当前数据库配置的所有映射关系,同时也负责维护当前的二级数据缓存和Statement Pool。由此可见,SessionFactory的创建过程非常复杂、

            代价高昂。这也意味着,在系统设计中充分考虑到SessionFactory的重用策略。由于SessionFactory采用了线程安全的设计,可由多个线程并发调用。

        ③. Session接口 

SessionHibernate持久化操作的基础,提供了众多持久化方法,如saveupdatedelete等。通过这些方法,透明地完成对象的增加、删除、修改、查找等操作。

同时,值得注意的是,HibernateSession的设计是非线程安全的,即一个Session实例同时只可由一个线程使用。同一个Session实例的多线程并发调用将导致难以预知的错误。

Session实例由SessionFactory构建:

Configuration config=new Configuration().configure();

SessionFactorysessionFactory=config.buldSessionFactory();

Session session=sessionFactory.openSession();

④. Transaction接口 

TransactionHibernate中进行事务操作的接口,Transaction接口是对实际事务实现的一个抽象,这些实现包括JDBC的事务、JTA中的UserTransaction,甚至可以是CORBA事务。之所以这样设计是可以让开发者能够使用一个统一的操作界面,使得自己的项目可以在不同的环境和容器之间方便地移值。事务对象通过Session创建。例如以下语句:

Transaction ts=session.beginTransaction();

⑤. Query接口 

Hibernate 2.x中,find()方法用于执行HQL语句。Hibernate 3.x废除了find()方法,取而代之的是Query接口,它们都用于执行HQL语句。QueryHQL是分不开的。

Query query=session.createQuery(“fromtable where id=1”);

例如以下语句:

Query query=session.createQuery("fromtable whereid=?");

就要在后面设置其值:

Query.setString(0,"要设置的值");

上面的方法是通过“?”来设置参数,还可以用“:”后跟变量的方法来设置参数,如上例可以改为:

Query query=session.createQuery("fromtable whereid=:1");

Query.setString("kchValue","要设置的课程号值");

其使用方法是相同的,例如:

Query.setParameter(0,"要设置的值");

Query还有一个list()方法,用于取得一个List集合的示例,此示例中包括可能是一个Object集合,也可能是Object数组集合。例如:

Query query=session.createQuery("fromtable whereid=1");

List list=query.list();

 五、如何在项目中使用Hibernate?以及如何优化Hibernate的使用?

六、总结。

原文地址:https://www.cnblogs.com/blogofwyl/p/5378536.html