Hibernate学习记录1 基本概念

来源:互联网 发布:企业it数据基础设施 编辑:程序博客网 时间:2024/05/16 05:50

Hibernate 持久化框架,开源的ORM框架。

Hibernate核心:

这里写图片描述

  • Configuration:对Hibernate进行配置,以及对它的启动。在Hibernate的启动过程中,Configuration类的实例首先定位映射文档的位置,读取这些配置,然后创建一个SessionFactory对象。虽然Configuration类在整个Hibernate项目中只扮演着一个很小的角色,但它是启动Hibernate时所遇到的第一个对象。
  • SessionFactory:负责初始化Hibernate。它充当数据存储源的代理,并负责创建Session对象。这里用到了工厂模式。需要注意的是SessionFactory并不是轻量级的,因为一般情况下,一个项目通常只需要一个SessionFactory。当需要操作多个数据库时,可以为每个数据库指定一个SessionFactory。
  • Session:负责执行被持久化对象的CRUD操作(CRUD的任务是完成与数据库的交流,包含了很多常见的SQL语句)。Session对象是非线程安全的。同时,Hibernate的Session不同于JSP应用中的HttpSession。
  • Trasaction:是一个可选的API,可以选择不使用这个接口,取而代之的是Hibernate的设计者自己写的底层事务处理代码 。Transaction接口是对实际事务实现的一个抽象,这些实现包括JDBC的事务、JTA中的UserTransaction、甚至可以是CORBA事务。
  • Query:方便地对数据库及持久对象进行查询。它可以有两种表达式:HQL或SQL。
  • Criteria:类似于Query接口,允许创建并执行面向对象的标准化查询。

优点:
- 数据操作对象化
- 代码便于移植
- 非侵入性的轻量及框架
- Hibernate代码测试方便
缺点:
- 使用数据库特性的语句,很难调优
- 批量数据更新存在问题
- 系统中存在大量的攻击查询功能

主键介绍

Assigned

由用户生成主键值,并且在save()之前指定。

Hilo

使用高低位算法生成主键,高低位算法使用一个高位值和一个低位值,然后把算法得到的两个值接起来作为数据库中的唯一主键。Hilo方式需要额外的数据库表和字段提供高位值来源,默认情况下是hibernate_unique_key,默认字段叫作next_hi。next_hi必须有一条记录,否则会出现错误。
Hilo需要额外的数据表的支持,能保证同一个数据库中主键的唯一性,但不能保证多个数据库之间主键的唯一性。Hilo主键生成方式由Hibernate维护,所以Hilo方式与底层数据库无关。但不应该手动修改Hilo算法使用的表的值。

Increment

自动主键。不合适多进程并发更新数据库,适合单一进程访问数据库。不能用于群集环境。

Identity

根据底层数据库,来支持自动增长。不同的数据库使用不同的主键增长方式。
特点:
与底层数据库有关,要求数据库支持Identity,如:
- Mysql:auto_increment
- SQL Server:Identity
不便于在多个不同的数据库之间移植程序。

Sequence

需要底层数据库支持Sequence,如Oracle、DB2、PostgreSql、SAPDb。

Native

根据不同的数据库自动选择Identity、Sequence、Hilo主键生成方式。

UUID

使用128位UUID算法生成主键,能够保证网络环境下的主键唯一性,也能够保证在不同数据库及不同服务器下主键的唯一性,但占用较多的存贮空间。

Foreigh GUID

用于一对一关系中。GUID主键生成方式使用了一种特殊算法,保证生成主键的唯一性,支持SqlServer和MySql。

缓存管理

Hibernate中提供了两级Cache,

一级缓存 Session级别

属于事务范围的缓存。这一级别的缓存由hibernate管理的,一般情况下无需进行干预。每个事务都有单独的第一级缓存进程范围或集群范围,缓存被同一个进程或集群范围内的所有事务共享,并发访问策略由于每个事务都拥有单独的第一级缓存,不会出现并发问题,无需提供并发访问策略。由于多个事务会同时访问第二级缓存中相同数据,因此必须提供适当的并发访问策略,来保证特定的事务隔离级别数据过期策略。处于一级缓存中的对象永远不会过期,除非应用程序显式清空缓存或者清除特定的对象。
物理存储介质内存和硬盘对象的数据首先存放在基于内存的缓存中,当内存中对象的数目达到数据过期策略中指定上限时,会将其余的对象写于基于硬盘的缓存中。

只要应用程序通过Session接口来执行数据操作,Hibernate就会启用第一级缓存,可以绕过Hibernate API,直接通过JDBC API来执行操作。
用户可以在单个类或类的单个集合的粒度中配置第二级缓存。如果类的实例被经常读但很少被修改,就可以考虑使用第二级缓存。只有为某个类或集合配置了第二级缓存,Hibernate在运行时才会把它的实例加入到第二级缓存中。
用户管理缓存的方式:一级缓存为内存,Session的evict()方法可以显式清空缓存中特定对象,但不推荐。
二级缓存为内存或硬盘,因此第二级缓存可以存放大量数据,数据过期策略的maxElementsInMemory属性值可以控制内存中的对象数目。
管理第二级缓存主要包括两个方面:选择需要使用第二级缓存的持久类、设置合适的并发访问策略。

一级缓存

当应用程序调用Session的save()、update()、saveOrUpdate()、get()或load(),以及调用查询接口的list()、iterate()、filter()方法时,如果在Session缓存中还不存在相应的对象,Hibernate就会把该对象加入到第一级缓存中。当清理缓存时,Hibernate会根据缓存中对象的状态变化来同步更新数据库。Session为应用程序提供了两个管理缓存的方法:evict(清除指定持久化对象)和clear(清空缓存中所有持久化对象)

二级缓存 SessionFactory级别

进程范围或集群范围的缓存。

过期策略

  • 条件查询时,总是发出一条select * from table where(选择所有字段)这样的SQL语句查询,一次获得所有的数据对象
  • 把获得的所有数据对象根据ID放入到第二级缓存中
  • 当Hibernate根据ID访问数据对象的时候,首先从Session一级缓存中查; 查不到,如果配置了二级缓存,那么从二级缓存查; 查不到,再查询数据库,把结果按照ID放入到缓存。
  • 删除、更新、增加数据时,同时更新缓存。
    Hibernate的二级缓存策略,是针对于ID查询的缓存策略,对于条件查询则毫无作用。为此,Hibernate提供了针对条件查询的Query Cache。

常用的缓存插件

缓存插件 支持只读 支持非严格读写 支持读写 支持事务 EhCache 是 是 是 OSCache 是 是 是 SwarmCache 是 是 JBossCache 是 是

默认情况下,Hibernate使用EhCache进行JVM级别的缓存。用户可以通过设置Hibernate配置文件中的hibernate.cache.provider_class属性,指定其它的缓存策略,该策略必须实现org.hibernate.cache.CacheProvider接口。

配置二级缓存的主要步骤

  • 选择需要使用二级缓存的持久化类,设置它的命名缓存并发访问策略
  • 选择合适的缓存插件,然后编辑该插件的配置文件

延迟加载

Hibernate 对象关系映射提供延迟的与非延迟的对象初始化。非延迟加载在读取一个对象的时候会将与这个对象所有相关的其它对象一起读取出来,这有时会导致成百的select语句在读取对象的时候执行。这个问题有时出现在使用双向关系的时候,经常会导致整修数据都在初始化的阶段被读出来了。

延迟加载机制,只在一个对象调用它的一对多或多对多关系时才将关系对象读取出来。这个过程对开发者来说是透明的,而且只进行了很少的数据操作请求,因此会得到比较明显的性能提升。一个缺陷是延迟加载技术要求一个Hibernate会话要在对象使用的时候一直开着,这会成为通过使用DAO模式将持久层抽象出来时的一个主要问题。为了将持久化机制完全地抽象出来,所有的数据库逻辑,包括打开或关闭会话都不能在应用层出现。

WEB层延迟加载

性能优化

HQL优化

API的正确使用主配置参数(日志、查询缓存、fetch_size,batch_size等)

缓存

  • fetch_size
  • batch_size
  • 生成系统,关掉sql语句打印
  • 数据库级缓存,这级缓存是最高效和安全的,但不同的数据库可管理的层次并不一样,如Oracle中可以在建表时指定将整修表置于缓存中
  • SESSION缓存
  • 应用缓存,在一个SessionFactory中有效,也是优化重中之重。将数据放在这一级缓存之前,需要考虑一些前提条件:
    1. 数据不会被第三方修改
    2. 数据不会太大
    3. 数据不会频繁更新
    4. 数据不是关键数据
  • 分布式缓存

延迟加载

方法选用

  • 如果返回十万记录,使用List/Set/Bag/Map处理,可能会内存不够,如果用基于游标(ScrollableResults)或Iterator的结果集,则不存在这样的问题。
  • Session的load/get方法,前者会使用二级缓存,后者则不会。
  • Query和list/iterator,list只能利用查询缓存,无法利用二级缓存中的单个实体,但list查出的对象会写入二级缓存,但它一般只生成较少的执行SQL语句,很多情况就是一条(无关联)
  • iterator则可以利用二级缓存,根据id使用缓存
  • 通过iterator,配合缓存管理API,在海量数据查询中可以很好的解决内存问题。

集合的选用

批量操作

映射文件优化(ID生成策略、二级缓存、延迟加载、关联优化)

事务控制策略



HQL

HQL使用步骤

HQL查询依赖于Query类。每个Query实例对应一个查询对象。

 Session session=HibernateSessionFactory.getSession(); String sqlStr="from Columns"; Query query=session.createQuery(sqlStr); List<Columns> list=query.list();
0 0
原创粉丝点击