`

Hibernate 总结

阅读更多
第一部分:简介

Hibernate

Hibernate是一个免费的开源Java包,它使得与关系数据库打交道变得十分轻松,就像您的数据库中包含每天使用的普通Java对象一样,同时不必考虑如何把它们从神秘的数据库表中取出(或放回到数据库表中)。它解放了您,使您可以专注于应用程序的对象和功能,而不必担心如何保存它们或稍后如何找到它们。

Hibernate的工作方式
Hibernate不会对您造成妨碍,也不会强迫您修改对象的行为方式。它们不需要实现任何不可思议的接口以便能够持续存在。惟一需要做的就是创建一份XML“映射文档”,告诉Hibernate您希望能够保存在数据库中的类,以及它们如何关联到该数据库中的表和列,然后就可以要求它以对象的形式获取数据,或者把对象保存为数据。

  第二部分:HIBERNATE - 符合Java习惯的关系数据库持久化简介

一、使用流程

1、配置Hibernate(session-factory――数据源(property)、映射配置文件(mapping))

2、持久化类

3、映射文件

4、单独使用时(实现一个HibernateUtil辅助类,应用ThreadLocal来实现访问安全)

5、操纵HIbernateAPI来工作

        SessionFactory是安全线程,可以由很多线程并发访问并获取到Sessions。单个Session不是安全线程对象,它只代表与数据库之间的一次操作。Session通过SessionFactory获得并在所有的工作完成后关闭。

    在一个Session中,每个数据库操作都是在一个事务(transaction)中进行的,这样就可以隔离开不同的操作(甚至包括只读操作)。

    Hibernate有不同的方法用来从数据库中取回对象。最灵活的方式就是使用Hibernate查询语言(HQL),这是一种容易学习的语言,是对SQL的面向对象的强大扩展。

二、Hibernate框架用到的几个重要的对象和概念

1、SessionFactory (org.hibernate.SessionFactory) 针对单个数据库映射关系经过编译后的内存镜像,它也是线程安全的(不可变)。 它是生成Session的工厂,本身要用到ConnectionProvider。 该对象可以在进程或集群的级别上,为那些事务之间可以重用的数据提供可选的二级缓存。

2、Session (org.hibernate.Session) 表示应用程序与持久储存层之间交互操作的一个单线程对象,此对象生存期很短。 其隐藏了JDBC连接,也是Transaction的工厂。 其会持有一个针对持久化对象的必选(第一级)缓存,在遍历对象图或者根据持久化标识查找对象时会用到。

3、事务Transaction (org.hibernate.Transaction) (可选的)应用程序用来指定原子操作单元范围的对象,它是单线程的,生存期很短。

4、ConnectionProvider(org.hibernate.connection.ConnectionProvider) (可选的)生成JDBC连接的工厂(同时也起到连接池的作用)。

5、TransactionFactory (org.hibernate.TransactionFactory) (可选的)生成Transaction对象实例的工厂。 6、扩展接口 Hibernate提供了很多可选的扩展接口,你可以通过实现它们来定制你的持久层的行为。在一个“轻型”的架构中,应用程序可能绕过 Transaction/TransactionFactory 以及 ConnectionProvider 等API直接跟JTA或JDBC打交道。

7、实例状态一个持久化类的实例可能处于三种不同状态中的某一种。

    瞬态(transient) 该实例从未与任何持久化上下文关联过。它没有持久化标识(相当于主键)。就是从未与 session 发生过关系的对象.

    持久(persistent) 和 Session 发生了关系的对象,并且此时 session 未关闭.实例目前与某个持久化上下文有关联。 它拥有持久化标识(相当于主键),并且可能在数据库中有一个对应的行。 对于某一个特定的持久化上下文,Hibernate保证持久化标识与Java标识(其值代表对象在内存中的位置)等价。

    脱管(detached) 就是与 session 发生过关系的对象,但 session 已经关闭了的情况下存在的对象实例曾经与某个持久化上下文发生过关联,不过那个上下文被关闭了, 或者这个实例是被序列化(serialize)到这个进程来的。 它拥有持久化标识,并且在数据库中可能存在一个对应的行。 对于脱管状态的实例,Hibernate不保证任何持久化标识和Java标识的关系。 

三、配置(使用时可以查询参考)

    由于Hibernate是为了能在各种不同环境下工作而设计的, 因此存在着大量的配置参数. 幸运的是多数配置参数都 有比较直观的默认值, 并有随Hibernate一同分发的配置样例hibernate.properties (位于etc/)来展示各种配置选项. 所需做的仅仅是将这个样例文件复制到类路径 (classpath)下做一些自定义的修改.

四、持久化类

五、对象/关系数据库映射基础(Basic O/R Mapping)

1、   配置

2、   使用 JDK 5.0 的注解(Annotation)

六、有关映射技术

1、集合类映

2、关联关系映射

3、组件映射

4、继承映射

七、与对象共事(使用API操纵对象)

    Hibernate是完整的对象/关系映射解决方案,它提供了对象状态管理(state management)的功能,使开发者不再需要理会底层数据库系统的细节。也就是说,相对于常见的JDBC/SQL持久层方案中需要管理SQL语句,Hibernate采用了更自然的面向对象的视角来持久化Java应用中的数据。

    换句话说,使用Hibernate的开发者应该总是关注对象的状态(state),不必考虑SQL语句的执行。 这部分细节已经由Hibernate掌管妥当,只有开发者在进行系统性能调优的时候才需要进行了解。

八、事务和并发

        Hibernate的事务和并发控制很容易掌握。Hibernate直接使用JDBC连接和JTA资源,不添加任何附加锁定 行为。

九、拦截器与事件

        应用程序能够响应Hibernate内部产生的特定事件是非常有用的。这样就允许实现某些通用的功能 以及允许对Hibernate功能进行扩展。

十、批量处理

        如果要将很多对象持久化,你必须通过经常的调用 flush() 以及稍后调用 clear() 来控制第一级缓存的大小。防止内存溢出异常,这是因为 Hibernate 把所有实例在 session级别的缓存区进行了缓存的缘故

         首先,如果你要执行批量处理并且想要达到一个理想的性能, 那么使用JDBC的批量(batching)功能是至关重要。将JDBC的批量抓取数量(batch size)参数设置到一个合适值 (比如,10-50之间);也可能想在执行批量处理时关闭二级缓存

        批量更新或者批量删除的最佳方式是直接通过JDBC API执行相关的SQL语句或调用相关的存储过程。

十一、查询

1、HQL: Hibernate查询语言

         除了Java类与属性的名称外,查询语句对大小写并不敏感。 所以 SeLeCT 与 sELEct 以及 SELECT 是相同的,但是 org.hibernate.eg.FOO 并不等价于 org.hibernate.eg.Foo 并且 foo.barSet 也不等价于 foo.BARSET。

2、条件查询(Criteria Queries) 

       具有一个直观的、可扩展的条件查询API是Hibernate的特色。

3、Native SQL查询

    也可以使用你的数据库的Native SQL语言来查询数据。这对你在要使用数据库的某些特性的时候(比如说在查询提示或者Oracle中的 CONNECT关键字),这是非常有用的。这就能够扫清你把原来直接使用SQL/JDBC 的程序迁移到基于 Hibernate应用的道路上的障碍。

    Hibernate3允许你使用手写的sql来完成所有的create,update,delete,和load操作(包括存储过程)

4、过滤数据

十二、提升性能

1、抓取策略(Fetching strategies) 

       连接抓取(Join fetching)         查询抓取(Select fetching)         子查询抓取(Subselect fetching)         批量抓取(Batch fetching)

    默认情况下,Hibernate3使用延迟查询抓取,对于多数应用中绝大部分的实体或集合,这是最佳选择。 如果你设置了hibernate.default_batch_fetch_size, Hibernate将根据这个批量抓取优化设置来进行延迟抓取(可以在更小的粒度上进行优化设置)。

        查询抓取(默认的)在N+1查询的情况下是极其脆弱的,因此我们可能会要求在映射文档中定义使用连接抓取。

         截然不同的一种避免N+1次查询的方法是,使用二级缓存。

    通常情况下,我们并不使用映射文档进行抓取策略的定制。更多的是,保持其默认值,然后在特定的事务中, 使用HQL的左连接抓取(left join fetch) 对其进行重载。这将通知 Hibernate在第一次查询中使用外部关联(outer join),直接得到其关联数据。 在条件查询 API中,应该调用 setFetchMode(FetchMode.JOIN)语句。

2、二级缓存(The Second Level Cache)

3、管理缓存(Managing the caches)

4、查询缓存(The Query Cache)

5、理解集合性能(Understanding Collection performance)

6、监测性能(Monitoring performance)

第三部分:推荐书籍

一、《Hibernate Reference》必读书籍,可以作为速查手册,感谢Redsaga组织的翻译工作,使得我们可以有中文版可看。 Hibernate参考文档3.0.2 http://www.redsaga.com/hibernate-ref/3.x/zh-cn/html/index.html

二、《Hibernate in action》 In action 系列的书籍也没啥多说的,强烈推荐看看。

三、《深入浅出Hibernate》 简称白皮书,^_^,是夏昕、曹晓刚以及唐勇三位大师的大作。

四、《精通Hibernate:Java对象持久化技术详解》         孙卫琴 编著 



补充: Hibernate性能优化
1、抓取优化

       如何抓取?抓取策略:连接抓取,查询抓取,子查询抓取,批量抓取

       何时抓取?立即,延迟(使用 OpenSessionInView模式,当请求开始时打开session,当请求响应结束时才关闭session)

       抓取粒度:指的是对象在关联关系之间被导航时一次预先加载的数量(batch-size)

 
默认情况下,Hibernate3使用延迟查询抓取

Oracle数据库的JDBC驱动默认的Fetch Size=15,设置Fetch Size设置为:30、50,性能会有明显提升,如果继续增大,超出100,性能提升不明显,反而会消耗内存

 
2、二级缓存

       对象缓存、查询缓存

3、批量数据操作

       需要注意两点,一,批量提交,二,及时清除不需要的一级缓存数据

4、杂项

       dynamic-insert,dynamic-update,动态插入和动态更新,指的是让Hibernate插入数据时仅插入非空数据,当修改数据时只修改变化的数据.

如果是超大的系统,建议生成htm文件。加快页面提升速度。

inverse = ?   mappedBy = ""

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics