Hibernate学习总结(一)

来源:互联网 发布:linux shell脚本例子 编辑:程序博客网 时间:2024/06/07 03:51

最近有朋友问关于Hibernate的一些问题,抽空的时候做了一个还算比较详细的总结,趁此机会也放在CSDN上和大家一起分享

首先我们应该明确一点,Hibernate是对JDBC进行了非常轻量的封装,是一个全自动的ORM(对象关系映射)框架,他可以自动生成SQL语句,也可以自动执行,让我们可以以面向对象的方式操作数据库,完成数据持久化的作用.

那什么是ORM呢?对象-关系映射简称ORM,用来把对象模型表示的对象映射到基于SQL的关系型数据库结构中去,只需要简单的操作实体对象的属性和方法.ORM技术在对象和关系型数据库中间起了一个桥梁的作用,前台的对象型数据和数据库中的关系型的数据通过这个桥梁来相互转化.

简单的说就是把我们程序中的实体类和数据库表建立对应关系.

Hibernate的优势:

①.Hibernate对JDBC访问数据库的代码做了轻量级封装,大大简化了数据访问层繁琐的重复性代码,并且减少了内存消耗,加快了运行效率.

②.Hibernate是一个基于JDBC的主流持久化框架,是一个优秀的ORM实现,它很大程度的简化了DAO(Data Access Object,数据访问对象)层编码工作.

③.Hibernate的性能非常好,映射的灵活性很出色。它支持很多关系型数据库,从一对一到多对多的各种复杂关系

④.可扩展性强,由于源代码的开源以及API的开放,当本身功能不够用时,可以自行编码进行扩展

我们要明确一点:

操作实体类就相当于操作数据库表

下面介绍一下映射文件的编写

映射文件通常是一个XML文件,但一般命名为类名.hbm.xml

<?xml version="1.0" encoding="UTF-8"?><!-- 导入约束:dtd约束位置:在Hibernate的核心jar包中名称为hibernate-mapping-3.0.dtd明确该文件中的内容:    实体类和表的对应关系    实体类中属性和表的字段的对应关系--><!DOCTYPE hibernate-mapping PUBLIC     "-//Hibernate/Hibernate Mapping DTD 3.0//EN"    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"><hibernate-mapping package="实体类所在包名"><!-- package属性用于设定包的名称,接下来该配置文件中凡是用到此包中的对象时都可以省略包名 -->    <!-- class标签            作用:建立实体类和表的对应关系            属性:                name:指定实体类的名称                table:指定数据库表的名称     -->    <class name="XXX" table="XXX">        <!-- id标签             作用:用于映射主键             属性:                name:指定的是属性名称。也就是get/set方法后面的部分,并且首字母要转小写。                column:指定的是数据库表的字段名称        -->        <id name="XXX" column="XXX">        <!-- generator标签:            作用:配置主键的生成策略。            属性:                class:指定生成方式的取值。                取值之一:native。使用本地数据库的自动增长能力。                mysql数据库的自动增长能力是让某一列自动+1。但是不是所有数据库都支持这种方式。             -->            <generator class="native"></generator>        </id>        <!-- property标签:                作用:映射其他字段                属性:                    name:指定属性的名称。和id标签的name属性含义一致                    column:指定数据库表的字段名称        -->        <property name="XXX" column="XXX"></property>    </class></hibernate-mapping>    

再来看一下主配置文件:

<?xml version="1.0" encoding="UTF-8"?><!-- 导入dtd约束:位置:在核心jar包中的名称为hibernate-configuration-3.0.dtd中--><!DOCTYPE hibernate-configuration PUBLIC    "-//Hibernate/Hibernate Configuration DTD 3.0//EN"    "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd"><hibernate-configuration><!-- 配置SessionFactory     SessionFactory就是一个工厂,用于生产Session对象的。    Session就是我们使用hibernate操作数据库的核心对象了。    明确:        此配置文件中的内容不需要背,很多配置都是可以在开发包中找到的。        但是要求必须知道:        创建SessionFactory由三部分组成,缺一不可。要知道是哪三部分            1、连接数据库的基本信息            2、hibernate的基本配置            3、映射文件的位置        找配置文件的key都是在hibernate的开发包中project文件夹下的etc目录中的hibernate.properties    -->    <session-factory>        <!-- 必要的配置信息:连接数据库的基本参数 -->        <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>        <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/day36_ee48_hibernate</property>        <property name="hibernate.connection.username">root</property>        <property name="hibernate.connection.password">root</property>        <!-- 2、hibernate的基本配置 -->        <!-- 数据库的方言 -->        <property name="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</property>        <!-- 是否显示SQL语句 -->        <property name="hibernate.show_sql">true</property>        <!-- 是否格式化SQL语句 -->        <property name="hibernate.format_sql">true</property>        <!-- 是否让hibernate根据表结构的变化来生成DDL语句             DDL:数据定义语言             hibernate可以根据映射文件来为我们生成数据库的表结构。             但是他不能生成数据库。            hbm2ddl.auto的取值                * none:不用Hibernate自动生成表.                * create:每次都会创建一个新的表.(测试)                * create-drop:每次都会创建一个新的表,执行程序结束后删除这个表.(测试)                * update:如果数据库中有表,使用原来的表,如果没有表,创建一个新表.可以更新表结构。                * validate:只会使用原有的表.对映射关系进行校验.        -->        <property name="hibernate.hbm2ddl.auto">update</property>        <!-- 3、映射文件的位置 -->        <mapping resource="XXX.hbm.xml"/>    </session-factory></hibernate-configuration>

Hibernate的配置文件,包含了连接持久层与映射文件所需的基本信息,其配置文件有两种格式,具体如下:一种是properties属性文件格式的配置文件,它使用键值对的形式存放信息,默认文件名称为hibernate.properties; 另一种是XML格式的配置文件,XML配置文件的默认名称为hibernate.cfg.xml。上述两种格式的配置文件是等价的,具体使用哪个可以自由选择。XML格式的配置文件更易于修改,配置能力更强,当改变底层应用配置时不需要改变和重新编译代码,只修改配置文件的相应属性即可,而properties格式的文件则不具有此优势,因此,在实际开发项目中,大多数情况会使用XML格式的配置文件。

简单介绍一下参数:

名称 用途 hibernate.dialect 操作数据库方言 hibernate.connection.driver_class 连接数据库驱动程序 hibernate.connection.url 连接数据库URL hibernate.connection.username 数据库用户名 hibernate.connection.password 数据库密码 hibernate.show_sq 在控制台上输出SQL语句 hibernate.format_sql are neat hibernate.hbm2ddl.auto 当SessionFactory创建时是否根据映射文件自动验证表结构或自动创建、自动更新数据库表结构。该参数的取值为:validate、update、create和create-drop。 hibernate.connection.autocommit 事务是否自动提交

Configuration对象

在使用Hibernate时,首先要创建Configuration实例,Configuration实例主要用于启动、加载、管理hibernate的配置文件信息。在启动Hibernate的过程中,Configuration实例首先确定Hibernate配置文件的位置,然后读取相关配置,最后创建一个唯一的SessionFactory实例。Configuration对象只存在于系统的初始化阶段,它将SessionFactory创建完成后,就完成了自己的使命。

Hibernate通常使用Configuration config = new Configuration().configure();的方式创建实例,此种方式默认会去src下读取 hibernate.cfg.xml配置文件。如果不想使用默认的hibernate.cfg.xml配置文件,而是使用指定目录下(或自定义)的配置文件,则需要向configure()方法中传递一个文件路径的参数,其代码写法如下:

Configuration config = new Configuration().configure("xml文件位置"); 

此种写法hibernate会去指定位置查找配置文件,例如,想要使用src下config包中的 hibernate.cfg.xml文件,只需将文件位置加入configure()中即可,其代码如下所示:

Configuration config = new Configuration().configure("/config/hibernate.cfg.xml");

加载映射文件

Hibernate除了可以使用Configuration对象加载核心配置文件以外,还可以利用该对象加载映射文件。因为如何使用properties文件作为Hibernate的核心配置文件,其他的属性可以使用key=value的格式来设置,但是映射没有办法加载。这时这个对象就有了用武之地。可以在手动编写代码的时候去加载映射文件。

Configuration configuration = new Configuration().configure("xml文件位置");configuration.addResource("XXX.hbm.xml");

SessionFactory接口

SessionFactory接口负责Hibernate的初始化和建立Session对象。它在Hibernate中起到一个缓冲区作用,Hibernate可以将自动生成的SQL语句、映射数据以及某些可重复利用的的数据放在这个缓冲区中。同时它还保存了对数据库配置的所有映射关系,维护了当前的二级缓存。

SessionFactory的创建:

SessionFactory sessionFactory = config.buildSessionFactory();

sessionFactory对象中维护了很多信息:

①.连接数据库的信息

②.hibernate的基本配置

③.一些预定义的SQL语句

④.hibernate的二级缓存

同时,他是有一个线程安全的对象,所有由该工厂生产的Session对象都共享工厂中维护的数据.

SessionFactory的使用原则:

由于SessionFactory维护了很多信息同时又是线程安全的,一般情况下,一个项目中只需要一个SessionFactory,只有当应用中存在多个数据源时,才为每个数据源建立一个SessionFactory实例。因此,不应该反复的创建和销毁.也就是说:一个应用应该只有一个SessionFactory。在应用加载时创建,应用卸载时销毁

在hibernate中使用数据源(连接池)

SessionFactory内部还维护了一个连接池,如果我们需要使用第三方的连接池如C3P0,那么需要我们自己手动进行配置

①.导入连接池的jar包

②.在hibernate主配置文件中配置

<!-- 配置数据源的提供商 --><property name="hibernate.connection.provider_class">    org.hibernate.connection.C3P0ConnectionProvider</property>

Session

Session 是应用程序与数据库之间交互操作的一个单线程对象,是 Hibernate 运作的中心,它的主要功能是为持久化对象提供创建、读取和删除的能力,所有持久化对象必须在session的管理下才可以进行持久化操作。

创建SessionFactory实例后,就可以通过它获取Session实例。获取Session实例有两种方式,一种是通过openSession()方法,另一种是通过getCurrentSession()方法。两种方法获取session的代码如下所示:

//采用openSession方法创建sessionSession session = sessionFactory.openSession();//采用getCurrentSession()方法创建sessionSession session = sessionFactory.getCurrentSession();

以上两种获取session实例方式的主要区别是,采用openSession方法获取Session实例时,SessionFactory直接创建一个新的Session实例,并且在使用完成后需要调用close方法进行手动关闭。而getCurrentSession方法创建的Session实例会被绑定到当前线程中,它在提交或回滚操作时会自动关闭。 在没有配置把Session绑定当前线程之前,getCurrentSession方法无法使用,如果要用getCurrentSession获取Session对象,则需要在主配置文件中写:

<!-- 开启线程绑定 -->        <property name="hibernate.current_session_context_class">thread</property>

关于Session我们需要注意几个细节:

①.由于SessionFactory已经维护了很多数据,所以Session就维护较少的内容。

②.它是一个轻量级对象。并且:它不是线程安全的!!!!!!!

③.它维护了hibernate的一级缓存

④它的反复创建销毁不会消耗太多资源。