下载安卓APP箭头
箭头给我发消息

客服QQ:3315713922

hibernate如何使用?有什么技巧吗?

作者:课课家教育     来源: http://www.kokojia.com点击数:1008发布时间: 2016-08-15 08:40:50

标签: hibernateweb应用java

Web开发

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

hibernate的工作过程

  可能有很多程序员都会这么认为,一旦使用类似Hibernate的对象关系映射工具(object-relational mapping tool),就再也不用担心持久化问题了,强大的Hibernate会处理好这一切。实际上这种想法是错误的。正因为使用Hibernate这种技术,程序员才更应该明白域对象(domain object)以及如何获取这些对象。这样的错误也一样会导致数据库发生异常。使用Hibernate,使程序员可以忽略对象和关系结构之间的不一致,同样,如果你要求它去做些傻事,它也会毫不犹豫地去做,比如可怕的n+1错误。所以你要记得,Hibernate除了不能帮你写代码,它可以做很多事情。

  以下是总结了一些关于使用Hibernate的经验,以及在使用过程中学习到的知识和技巧。

  如何定义实体

  实体定义是持久化策略(或许也是整个应用)中最重要的。因为所有的对象都是从核心对象集合中繁衍而来的,所以正确的定义实体很重要。下面是构建Hibernate/JPA实体方面的一些建议。

  1.创建一个新类,实现java.io.Serializable接口(并且显式定义serial Version UID这个变量)。

  2.增加类变量,@Id Serializableid和@Version Date last Updated,这两个变量分别是数据库主键(primary key)和实现乐观锁(optimistic locking)的版本号标记。

  3.增加任何需要的属性。

  4.写一个缺省的构造器。所有类型的变量都应该在这里初始化,包括集合(Collection)、列表(List)、集合(Set)等。

  5.为所有的属性创建getter和setter方法:

  1)应该为id和last Updated创建public getter方法,但不要创建setter方法。

  2)应该为Collection、List、Set等类型的变量创建public getter方法,但不要创建setter方法。Public getter方法最好返回一个不能修改的list。

  6.增加JPA/Hibernate注解。给getter方法增加注解。(或者我可以直接在变量上增加注解吗?)

  1)添加Hibernate合法性注解,例如@Not Null、@Length、@Range等。

  2)即使名字相同,也应该添加@Column(name=xxx)注解。如果你不想忘记数据所依赖的最初列名。

  3)在定义关系的实体中增加@One to One、@One To Many、@Many To One或者@Many To Many注解。

  7.如果使用关系映射,确保其是双向的(bidirectional)。为了简单,可以创建工具方法(utility method)来处理关系映射的一端:集合(Collection)类型的属性有工具方法add XXX和remove XXX。(或许对应的关系映射的另一端类的setter方法应该设为受保护的(protected),然后从工具方法中调用。)

  8.实现equal和hashcode方法。这个很重要!

  1)使用id的方式来进行比较,从而减少比较次数。

  2)使用Hibernate.is Initialized()方法,以判断是否存在代理实例或者代理实例是否被初始化。

  3)写equal和hashcode方法时,不是所有的成员(field)都要用上,而是应该使用那些真正可以区分不同对象的成员。

  9.用jakartacommons的To String Builder构建自己的to String()方法,使调试更加容易。

hibernate

  10.给spring的配置文件增加一个映射元素。

  1)get()方法和load()方法分析

  Session#get()和Session#load()一个很重要的区别,就是对于数据库读取效率的影响不同。get()方法从数据库返回一个对象实例,而load()方法则返回一个对象代理(proxy),当实际使用时才从当前session中返回对象实例。当使用load()时,是没有实际访问数据库的。这个时候只是通过对象的属性(非id)进行初始化工作。当进行实例赋值的时候使用load(),即意味着并不是想立刻获得对象的数据,而是得到一个标识符(identifier)从而建立起关联。还有一点很重要,就是如果数据库中不存在对应的行时使用load()方法,那么程序会抛出Object Not Found Exception异常。

  2)单元测试断言(Unit Testing Assertion)

  单元测试时使用Session#flush()和Session#evict(),分别向数据库写数据以及清除一级缓存(内存中),从而使接下来的程序能够验证修改是否被写入了数据库。evict()方法保证下次再去读同一个实例时,拿到的不是一级缓存中的对象,而是从数据库里拿出来的最新的对象。

  Session#close()用来关闭当前session并且检查延迟加载(lazy association)的状态,如果没有拿到期望的数据,那么就会抛出一个Lazy Initialization Exception异常。

  11.hibernate的缓存管理

  在Hibernate中,提供了两级Cache(高速缓冲存储器)。第一级别的缓存是Session级别的缓存,它是属于事务范围的缓存。这一级别的缓存由hibernate管理的,一般情况下不需要进行干预;第二级别的缓存是Session Factory级别的缓存,它属于进程范围或群集范围的缓存。这一级别的缓存可以进行配置和更改,并且可以动态加载和卸载。Hibernate还为查询结果提供了一个查询缓存,它依赖于第二级缓存。

  以上便是关于hibernate的一些基础知识和使用过程中应用到的技巧,希望对你有帮助!

赞(29)
踩(1)
分享到:
华为认证网络工程师 HCIE直播课视频教程