Hibernate 学习教程

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Hibernate 学习教程相关的知识,希望对你有一定的参考价值。

Hibernate 学习大纲

Hibernate 学习大纲    1

一、    Hibernate 入门    2

1.    Hibernate介绍    2

2.    Hibernate环境搭建    2

3.    实体映射文件    2

4.    Hibernate操作数据库    2

5.    list,iterate区别    2

6.    Hibernate常用接口和类介绍    3

7.    Session 接口专题    3

8.    实体对象的四种状态    5

二、    Hibernate 对象间的关联关系    6

1.    多对一关联映射    6

2.    一对多关联映射    6

3.    多对多关联映射    6

4.    一对一关联映射    6

5.    Open Session In View模式    6

6.    级联(cascade),反转(inverse),延迟加载,检索策略,和set元素介绍    6

三、    HQL查询    7

1.    HQL介绍    7

2.    HQL使用    7

3.    条件查询    8

4.    聚合函数    8

5.    参数绑定    8

6.    聚合函数    8

7.    模糊查询    8

8.    分组,筛选    8

9.    分页    8

10.    子查询    8

11.    连接查询    8

12.    命名查询    9

四、    Criteria 查询    9

五、    Hibernate调用本地SQL语句    9

六、    Hibernate优化    9

七、    Hibernate 注解    9

八、    Struts2 与 Hibernate 的集成    9

 

 

  1. Hibernate 入门

  1. 什么是ORM

    ORM(Object/Relationship Mapping) 对象/关系映射;

    利用面向对象思想编写的数据库应用程序最终都是把对象信息保存到关系型数据库中,于是要编写很多和底层数据相关的的SQL语句。

    1. Hibernate介绍

      Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,它将POJO与数据库表建立映射关系,是一个全自动的orm框架,hibernate可以自动生成SQL语句,自动执行,使得Java程序员可以随心所欲的使用对象编程思维来操纵数据库。 Hibernate可以应用在任何使用JDBC的场合,既可以在Java的客户端程序使用,也可以在Servlet/JSPWeb应用中使用,最具革命意义的是,Hibernate可以在应用EJBJ2EE架构中取代CMP,完成数据持久化的重任。

  2. Hibernate环境搭建

    1. 拷贝Hibernate基本jar包

      技术分享

        Maven

            <dependency>

                <groupId>org.hibernate</groupId>

                <artifactId>hibernate-core</artifactId>

                <version>4.3.11.Final</version>

            </dependency>

            <dependency>

                <groupId>antlr</groupId>

                <artifactId>antlr</artifactId>

                <version>2.7.7</version>

            </dependency>

            <dependency>

                <groupId>org.apache.avro</groupId>

                <artifactId>avro</artifactId>

                <version>1.6.3</version>

            </dependency>

            <dependency>

                <groupId>dom4j</groupId>

                <artifactId>dom4j</artifactId>

                <version>1.6.1</version>

            </dependency>

            <dependency>

                <groupId>org.hibernate.common</groupId>

                <artifactId>hibernate-commons-annotations</artifactId>

                <version>4.0.2.Final</version>

            </dependency>

            <dependency>

                <groupId>org.hibernate</groupId>

                <artifactId>hibernate-core</artifactId>

                <version>4.2.2.Final</version>

            </dependency>

            <dependency>

                <groupId>com.fasterxml.jackson.core</groupId>

                <artifactId>jackson-core</artifactId>

                <version>2.9.2</version>

            </dependency>

            <dependency>

                <groupId>org.codehaus.jackson</groupId>

                <artifactId>jackson-mapper-asl</artifactId>

                <version>1.9.2</version>

            </dependency>

            <dependency>

                <groupId>org.javassist</groupId>

                <artifactId>javassist</artifactId>

                <version>3.15.0-GA</version>

            </dependency>

            <dependency>

                <groupId>org.jboss.logging</groupId>

                <artifactId>jboss-logging</artifactId>

                <version>3.1.0.GA</version>

            </dependency>

            <dependency>

                <groupId>org.apache.lucene</groupId>

                <artifactId>lucene-core</artifactId>

                <version>3.6.2</version>

            </dependency>

            <dependency>

                <groupId>com.thoughtworks.paranamer</groupId>

                <artifactId>paranamer</artifactId>

                <version>2.3</version>

            </dependency>

            <dependency>

                <groupId>org.slf4j</groupId>

                <artifactId>slf4j-api</artifactId>

                <version>1.6.1</version>

            </dependency>

            <dependency>

                <groupId>org.xerial.snappy</groupId>

                <artifactId>snappy-java</artifactId>

                <version>1.0.4.1</version>

            </dependency>

    技术分享

  3. 实体映射文件

    Hibernate 的内置映射类型通常使用和Java类型相同的名字,它能够把Java基本类型,Java时间额日期类型,Java大对象类型及JDK中常用的Java类型映射到相应的标准SQL类型

     

    Hibernate映射类型

    Java类型

    标准SQL类型

    大小

    integer或int

    int或者java.lang.Integer

    INTEGER

    4字节

    long

    long或者java.lang.Long

    BIGINT

    8字节

    short

    short或者java.lang.Byte

    SMALLINT

    2字节

    byte

    byte或者java.lang.Byte

    TINYINT

    1字节

    float

    float或者java.lang.Float

    LOAT

    4字节

    double

    double或者java.lang.Double

    DOUBLE

    8字节

    character

    char或者java.lang.Character

    或者java.lang.String

    CHAR(1)

    定长字符

    string

    java.lang.String

    ARCHAR

    可变字符串

    boolean

    boolea或者java.lang.Boolean

    BIT

    布尔类型

    yes_no

    boolea或者java.lang.Boolean

    CHAR(1)(Y/N)

    布尔类型

    true_false

    boolea或者java.lang.Boolean

    CHAR(1)(Y/N)

    布尔类型

     

    Java时间和日期类型的Hibernate映射类型

     

    映射类型

    Java类型

    标准SQL类型

    描述

    date

    java.util.Date或者java.sql.Date

    DATE

    代表日期,形式为:YYYY-MM-DD

    time

    java.util.Date或者java.sql.Time

    TIME

    代表时间,形式为:HH:MM:SS

    timestamp

    java.util.Date或者java.sql.Timestamp

    TIMESTAMP

    代表时间和日期,形式为:YYYY-MM-DD HH:MM:SS

    calendar

    java.util.Calendar

    TIMESTAMP

    代表时间和日期,形式为:YYYY-MM-DD HH:MM:SS

    calendar_date

    java.util.Calendar

    DATE

    代表日期,形式:YYYY-MM-DD

     

    Java大对象类型的Hibernate映射类型

     

    映射类型

    Java类型

    标准SQL类型

    MySQL类型

    Oracle类型

    binary

    byte[]

    VARBINARY或者BLOB

    BLOB

    BLOB

    text

    java.lang.String

    CLOB

    TEXT

    CLOB

    serializable

    实现java.io.Serializable接口的任意一个Java类

    VARBINARY或者BLOB

    BLOB

    BLOB

    clob

    java.sql.Clob

    CLOB

    TEXT

    CLOB

    blob

    java.sql.Blob

    BLOB

    BLOB

    BLOB

     

    JDK自带的个别Java类的Hibernate映射类型

     

    映射类型

    Java类型

    标准SQL类型

    class

    java.lang.Class

    VARCHAR

    locale

    java.util.Locale

    VARCHAR

    time

    java.util.TimeZone

    VARCHAR

    currency

    java.util.Currency

    VARCHAR

  4. Hibernate操作数据库

    1. 创建SessionFactory

    SessionFactory sf = null;

    1. 读取配置文件并解析

    Configuration config = new Configuration.configure();

    1. 获得SessionFactory    【Hibernate 4.0 之前的方式】

    sf = config.buildSessionFaction();

         ③ 获得SessionFactory 【4.0 之后的方式】

    1. 创建一个ServerRegistry对象【Hibernate的任何配置和服务都需要在该对象注册后才有效】

    ServiceRegistry sr = new ServiceRegistryBuilder().applySettings(config.getProperties()).buildServiceRegistry();

    sf = config.buildSessionFactory(sr);

    1. 创建一个Session

    Session session = sf.openSession();

    1. 开启事务

    Transaction tran = session.beginTransaction();

    1. 执行数据库操作

        

    方法

    方法说明

    save()

    插入

    update()

    修改

    saveOrUpdate()

    修改或者更新

    get()

    查询数据不存在的时候会报错

    load()

    延迟加载数据,可以再class中配置lazy = false 修改为立即加载

    list()

    查询

    iteratr()

    查询

     

    1. 提交事务

    tran.commit();

    1. 释放资源

    session.close();

    sf.close();

  5. list,iterate区别

  • 使用list()方法获取查询结果,每次发出一条查询语句,获取全部数据
  • 使用iterate()方法获取查询结果,先发出一条SQL 语句用来查询满足条件数据的id,然后依次按这些id 查询记录,也就是要执行N+1 条SQL 语句(N 为符合条件的记录数)

 

  • list()方法将不会在缓存中读取数据,它总是一次性的从数据库中直接查询所有符合条件的数据,同时将获取的数据写入缓存
  • iterate()方法则是获取了符合条件的数据的id 后,首先根据id 在缓存中寻找符合条件的数据,若缓存中无符合条件的数据,再到数据库中查询
  1. Hibernate常用接口和类介绍

    1. Configuration

      负责管理Hibernate的配置信息,

    2. SessionFactory 接口
    3. Session 接口
    4. Transaction 接口
  2. Session 接口专题

    1、作用:提供基本的保存,删除,更新,和加载Java对象

     

    2、什么是清理缓存:

        Session能够在某些时间点,按照缓存中对象的变化来执行相关的SQL语句,来同步更新数据库,这一过程别称为清理缓存(flush)

     

    3、SessionFactory是线程安全的(可以多个对象共用同一个对象)。而Session不是线程安全的。

    为了解决Session线程不安全我们采用ThreadLocal方案。

     

    ThreadLocal 模式的解决方案:

        ThreadLocal并不是一个线程的本地实现,也就是说它不是一个Thread,而是Thread local variable(线程局部变量)。它的作用就是为每一个使用这个变量的线程提供一个变量的副本,并且每一个线程都可以独立地改变自己的副本,而不会和其它线程的副本冲突。

     

    ThreadLocal模式实例代码:

    public void getSession() {

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

            SessionFactory sf = cfg.buildSessionFactory();

            session = sf.openSession();

        }

     

        //创建ThreadLocal对象

        private static final ThreadLocal threadLodacl = new ThreadLocal();

        public void getSession() {

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

            SessionFactory sf = cfg.buildSessionFactory();

    //session = sf.openSession();

            //解决session线程非安全的方式

            this.session = (Session) threadLodacl.get();

            if(session == null){

                this.session = sf.openSession();

                threadLodacl.set(this.session);

            }

        }

     

    4、获取session的两种方式介绍

    1. getCurrentSession创建的Session会绑定到当前线程,而openSession不会
    2. getCurrentSession创建的Session会在事务回滚或者事务提交后自动关闭,而openSession创建的必须手动关闭(调用Session的cloe()方法)
    3. getCurrentSession使用方法
      1. 当使用本地使唔时(jdbc事务)

      需要在hibernate.cfg.xml文件的<session-factor>节点添加:

    <property name="hibernate.current_session_context_class">thread</property>

    1. 当使用的是全局使唔时(jta事务)

    <property name="hibernate.current_session_context_class">jta</property>

    注意:如果使用了getCurrentSession方法又没有在配置中配置以上方法时程序编译无误,但是运行汇报如下错误。

    Exception in thread "main" org.hibernate.HibernateException: No CurrentSessionContext configured!

    at org.hibernate.impl.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:620)

     

    5、Session的get()与load()

        

    6、Session接口常见方法

     

    序号

    Session 方法及说明

    1

    Transaction beginTransaction()
    开始工作单位,并返回关联事务对象。

    2

    void cancelQuery()
    取消当前的查询执行。

    3

    void clear()
    完全清除该会话。

    4

    Connection close()
    通过释放和清理 JDBC 连接以结束该会话。

    5

    Criteria createCriteria(Class persistentClass)
    为给定的实体类或实体类的超类创建一个新的 Criteria 实例。

    6

    Criteria createCriteria(String entityName)
    为给定的实体名称创建一个新的 Criteria 实例。

    7

    Serializable getIdentifier(Object object)
    返回与给定实体相关联的会话的标识符值。

    8

    Query createFilter(Object collection, String queryString)
    为给定的集合和过滤字符创建查询的新实例。

    9

    Query createQuery(String queryString)
    为给定的 HQL 查询字符创建查询的新实例。

    10

    SQLQuery createSQLQuery(String queryString)
    为给定的 SQL 查询字符串创建 SQLQuery 的新实例。

    11

    void delete(Object object)
    从数据存储中删除持久化实例。

    12

    void delete(String entityName, Object object)
    从数据存储中删除持久化实例。

    13

    Session get(String entityName, Serializable id)
    返回给定命名的且带有给定标识符或 null 的持久化实例(若无该种持久化实例)。

    14

    SessionFactory getSessionFactory()
    获取创建该会话的 session 工厂。

    15

    void refresh(Object object)
    从基本数据库中重新读取给定实例的状态。

    16

    Transaction getTransaction()
    获取与该 session 关联的事务实例。

    17

    boolean isConnected()
    检查当前 session 是否连接。

    18

    boolean isDirty()
    session 中是否包含必须与数据库同步的变化?

    19

    boolean isOpen()
    检查该 session 是否仍处于开启状态。

    20

    Serializable save(Object object)
    先分配一个生成的标识,以保持给定的瞬时状态实例。

    21

    void saveOrUpdate(Object object)
    保存(对象)或更新(对象)给定的实例。

    22

    void update(Object object)
    更新带有标识符且是给定的处于脱管状态的实例的持久化实例。

    23

    void update(String entityName, Object object)
    更新带有标识符且是给定的处于脱管状态的实例的持久化实例。

     

  3. Hibernate主键生成策略

    技术分享

  4. 实体对象的四种状态

    Hibernate操作的对象有四种状态:

    1、瞬时状态(Transient)/临时。2.、持久化状态(persistent)。3、托管状态(detached)/游离状态

    技术分享

    1、当一个对象通过new 新创建的时候就是瞬时状态

        瞬时状态下对象的主键没有值,也没有纳入session的管理,数据库表中也没有对应的记录,当我们调用save等相关的其他方法是则进入了持久化状态,

    2、持久化状态下对象纳入了session管理中,对象标示符有值。Hibernate保证在同一个session实例的缓存中数据库中的一条记录只对应唯一的一个持久化对象。session在清理缓存时会根据持久化对象的属性变化会同步更新数据库。当session关闭后持久化状态就会变成托管状态。当持久化对象调用delete方法就由持久化变成了移除状态

    3、托管状态下的特点:对象不处于session的管理中。但他曾经与某个持久化上下文发生过关联(session),对象标示符有值,数据库可能存在与之相对的记录。Hibernate不能够保证托管状态下的数据和数据库中的数据同步更新。

    4、临时和游离状态下的对象特点:等待垃圾回收,

  5. Hibernate 对象间的关联关系

    1. 多对一关联映射

    2. 一对多关联映射

      如何对集合进行排序:

      1. 在HQL 语句中排序
      2. 在set 元素中排序

        <set name="" inverse="true" order-by="排序列 排序方式"

                <ket column="" />

                <one-tomany class=""/>

        </set>

         

        <bag name="">

                <ket column="" />

                <one-tomany class=""/>

        </bag>

  6. 多对多关联映射

     

  7. 一对一关联映射

     

  8. Open Session In View模式

    技术分享

  9. 级联(cascade),反转(inverse),延迟加载,检索策略,和set元素介绍

    1、级联

    常用的cascade属性取值

    cascade属性值

    描述

    none

    当Session操作当前对象时,忽略其他关联的对象,它是cascade属性的默认值

    save-update

    当通过Session的save(),update(),及saveOrUpdate()方法来保存或更新当前对象时,级联保存所有关联的新建的瞬时状态的对象,并且级联更新所有关联的游离状态的对象

    delete

    当通过Session的delete()方法删除当前对象时,会级联删除所有关联的对象

    all

    包含save-update,delete的行为

     

    2、控制反转

        inverses属性指定了关联关系中的方向

        inverse 设置为false,则为主动房,由主动方负责维护关联关系,默认是false。

        inverse 设置为true,不负责维护关联关系。

    建议:

    1. 一般在一对多的时候在一的一方设置inverse 设置为true有助于性能提升。

    1. 在简历两个对象的双向关联时,应该同时修改两个关联对象的相关属性。

        2.建议inverse设置为true

     

    1. 延迟加载:延迟加载(lazy load 懒加载)是当真正需要数据时,才执行SQL语句进行查询。避免了无谓的开销。

     

    3、检索策略

            

    检索策略

    运行机制

    立即检索

    立即加载与当前对象关联的对象,需要执行多条select语句

     

    延迟检索

    不立即加载与当前对象关联的对象,在第一次访问关联对象时才加载其信息

     

    迫切左外连接检索

    通过左外连接加载与当前对象的关联对象。为立即检索策略,但执行的select语句少,只执行1条select连接查询语句

            

    属性

    类级别

    一对多关联级别

    多对一关联级别

     

     

    lazy

     

    1.<class>元素中lazy属性的可选值为:true(延迟检索)和false(立即检索)

     

    2. <class>元素中lazy属性的默认值为true

    1.<set>元素中lazy属性的可选值为:true(延迟检索)、false(立即检索)和extra(增强延迟检索)

    2. <set>元素中lazy属性的默认值为true

    1.<many-to-one>元素中的lazy属性的可选 值为:proxy(延迟检索)、no-proxy(无代理延迟检索)和false(立即检索)

    2.<many-to-one>元素中的lazy属性的默认值为true

     

     

    fetch

     

     

    没有此属性

    1.<set>元素中fetch属性的可选值为:select(查询语句)、subselect(子查询语句)和join(迫切左外连接检索)

    2. <set>元素的fetch属性的默认值为select

    1.<many-to-one>元素中fetch属性的可选 值为:select(查询语句)和join(迫切左外连接检索)

    2.<many-to-one>元素的fetch属性的默认值为select

        

    1、检索方法

        a) 通过Session类的get和load方法加载指定的OID的对象

        b) 通过HQL,QBC等检索方法记载满足条件的对象

    2、检索的作用域

        a) 类级别:作用于当前对象。对当前对象时立即检索,还是延迟检索。默认延迟检索只对load有效

        b) 关联级别:对关联对象是立即检索,延迟检索还是迫切左外连接检索。默认延迟检索。对所有检索方法有效

     

    3、fetch的作用和取值

        a) select     加载关联对象时通过select语句实现。默认值

        b) subselect     加载关联对象时通过带子查询语句实现。

        c) join 执行立即检索,采用迫切左外连接检索所有关联对象,lazy属性将被忽略。

     

    总结:① select 和 subselect 适用于立即检索和延迟检索,join 仅使用立即检索。

    ② select 和 subselect 决定加载关联对象时查询语句形式,join决定加载关联对象的时机。

     

  10. HQL查询

    1. HQL介绍

  11. HQL使用

        一、实体查询(查询持久化类的全部信息)

        Query 的list,iterate,uniqueresult方法    区别

        List,查询一次,返回满足条件的全部信息的所有字段

        Iterate方法,从数据库中检索出所有符合条件的所有记录,仅包含ID字段。

            如果缓存中包含全部数据,无需再查询数据库直接应用(1+0)

            如果缓存中不包含任何数据,需在查询数据库n次,依次查询各条记录(1+n)

            大多数情况下进行list查询,当对象包含大量属性,或者需要加载大部分数据已经存在缓存中,可以使用iterate()

  12. 条件查询

  13. 聚合函数

  14. 参数绑定

    1. 占位符"?"
    2. 命名查询
    1. 封装参数(投影查询)

      技术分享

  15. 聚合函数

    count(),sum(),max(),min(),avg()

  16. 模糊查询

  17. 分组,筛选

  18. 分页

  19. 子查询

    1. 连接查询

    连接类型

    HQL语法

    左外连接

    left outer join 或者 left join

    迫切左外连接

    left outer join 或者 left join fetch

    内连接

    inner join 或者 join

    迫切内连接

    inner join fetch 或者 join fetch

    右外连接

    right out jonin 或者 right join

  20. 命名查询

    技术分享

  21. Criteria 查询

  22. Hibernate调用本地SQL语句

  23. Hibernate优化

    1、避免or操作

    where 子句包含or 操作,执行时不使用索引

    可以使用in条件来替换

     

    2、避免使用not

    where 子句包含not 关键字,执行时该字段的索引失效

    使用比较运算符替换not

     

    3、避免like的特殊形式

    查询时,尽可能少使用like

     

    4、避免having子句

    尽可能在where 子句中指定条件

     

    5、避免使用distinct

    在不要求或允许冗余时,应避免使用distinct

  24. Hibernate 注解

     

  25. Struts2 与 Hibernate 的集成
























以上是关于Hibernate 学习教程的主要内容,如果未能解决你的问题,请参考以下文章

Hibernate学习笔记_02

框架学习 Hibernate框架学习 Hibernate概念和api使用

[原创]java WEB学习笔记77:Hibernate学习之路---Hibernate 版本 helloword,

Hibernate 学习-2

Hibernate基础学习—Hibernate相关API介绍

Hibernate 学习路程之一(Hibernate 环境的搭建)