对象/关系映射— hibernate

53
对对 / 对对对对— Hibernate 作作 作作作作 :( Moxie Email:achqian@yahoo. com.cn 对对对对作作 Java SQL JDBC 作作作作作作作作作作作 作作作作作作作 作作作 对对对对作作 O/R Mapping 作作 作作 Hibernate 作作作作作作作 作作 作作 Hibernate 作作作作作作作作

Upload: lucie

Post on 18-Mar-2016

331 views

Category:

Documents


8 download

DESCRIPTION

对象/关系映射— Hibernate. 作者:钱安川( Moxie ). 学员要求 : 熟悉 Java、SQL、JDBC, 掌握面向对象的开发方法,并有实际项目开发经验 课程目标: 理解 O/R Mapping 原理,掌握 Hibernate 开发的相关知识,并能使用 Hibernate 进行实际项目开发. Email:[email protected]. 目录. 一、持久化层- O/R Mapping 二、 Hibernate 入门 三、 Hibernate 映射申明( Mapping declaration ) 四、持久化对象的状态和生命周期 - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: 对象/关系映射— Hibernate

对象 / 关系映射— Hibernate

作者:钱安川( Moxie )

Email:[email protected]

学员要求:熟悉 Java 、 SQL 、 JDBC ,掌握面向对象的开发方法,并有实际项目开发经验课程目标:理解 O/R Mapping 原理,掌握 Hibernate 开发的相关知识,并能使用 Hibernate 进行实际项目开发

Page 2: 对象/关系映射— Hibernate

目录一、持久化层- O/R Mapping二、 Hibernate 入门三、 Hibernate 映射申明( Mapping declaration )四、持久化对象的状态和生命周期五、 Hibernate 查询六、 Hibernate 最佳实践

Page 3: 对象/关系映射— Hibernate

一、持久化层- O/R Mapping

基于 B/S 的典型三层架构如何分层?业务逻辑层和持久化层绝不要依赖于展现层。使用假设法测试。例子: 1 、一个显示课程考试分数的列表。现在要将不及格的分数用红色字体显示(低于 60分)。2 、搜索。

Page 4: 对象/关系映射— Hibernate

如何进行对象-关系数据库的匹配public class User {

private String name; private String password;

private List address;………}create table tbl_user (

name varchar(255) not null ,

password varchar(255),……….

primary key (name))

如何进行对象-关系数据库的匹配?对象 关系数据库

类的属性(基本类型) 表的列类 表1:n/n:1 外键n:m 关联表继承 单表继承、具体表继承、类表继承

Page 5: 对象/关系映射— Hibernate

对象—关系数据库的不匹配范式 粒度( granularity )的问题 子类型( subtypes )的问题 同一性( identity )的问题 与关联( associations )有关的问题 对象结构导航 (navigation) 的问题 范式不匹配的代价 花费很多时间和精力来手工实现对象和关系的匹配。 甚至要扭曲对象模型直到它与下层的关系技术匹配为止。 JDBC API 本身的问题。 JDBC 和 SQL 提供了一个面向语句(即命令 ) 的 方 法 从 SQL 数 据 库 中 来 回 移 动 数 据 。 至 少 在 三 个 时 刻

( Insert , Update , Select )必须指定一个结构化关系,这增加了设计和实现所需要的时间。

Page 6: 对象/关系映射— Hibernate

基于关系数据库的持久层可选方案优点 缺点

SQL/JDBC

成熟,流行,使用 DAO模式 代码烦杂,可读性差,维护困难,移植困难Entity Bean

CMP ( EJB1.1 之后),未来的 EJB3错误的设计。不可移植,依赖性强,不可序列化,不支持多态的关联查询

JDO 简单、透明、标准 不够成熟

Page 7: 对象/关系映射— Hibernate

基于关系数据库的持久层可选方案优点 缺点

Apache OJB

性能、稳定性,属于Apache 基金组织 文档资源太少,支持标准太多成了负担( ODMG

3.0 , JDO1.0 )iBATIS 可以控制更多的数据库操作细节。实用于遗留系统的改造和对既有数据库的

复用。

持久层封装不够彻底,只是一个 DBHelper 。

Hibernate 成熟、流行、功能强大。并逐渐发展成 Java 持久层事实上的标准。不够透明

Page 8: 对象/关系映射— Hibernate

O/R Mapping -What? Why?

什么是 O/R Mapping?对象 - 关系映射是一门非常实用的工程技术,它实现了 Java应用中的对象到关系数据库中的表的自动的(和透明的)持久化,使用元数据( meta data )描述对象与数据库间的映射。 O/R Mapping 的优点 提高生产率( Productivity ) 可维护性( Maintainability ) 更好性能( Performance ) 厂商独立性( Vendor independence )

Page 9: 对象/关系映射— Hibernate

二、 Hibernate 入门 Hibernate 概述 Hibernate 是非常优秀、成熟的 O/R Mapping框架。它提供了强大的对象和关系数据库映射以及查询功能。 Hibernate 优势 开源 (LGPL) 成熟 流行 (约 13 000 downloads/month) 自定义 API JBoss 将用 Hibernate3 实现 Entity Beans

Page 10: 对象/关系映射— Hibernate

Hibernate 开发步骤一、持久化类的设计二、持久化类和关系数据库的映射三、应用的开发

Page 11: 对象/关系映射— Hibernate

持久化 Java 类必须遵循的原则 为类的持久化类字段申明访问方法( get/set )。 Hibernate 对

JavaBeans风格的属性实行持久化。 实现一个默认的构造方法( constructor )。这样的话 Hibernate就可以使用 Constructor.newInstance() 来实例化它们。 如果是集合类型的属性,它的类型必须定义为集合的接口。例如:

List 、 Set 。

提供一个标识属性( identifier property )。如果没有该属性,一些功能不起作用,比如:级联更新( Cascaded updates ) Session.saveOrUpdate() 。

Page 12: 对象/关系映射— Hibernate

持久化类和关系数据库的映射

XDoclet :它通过在 Java 源代码中加入特定的 JavaDoc tag ,从而为其添加特定的附加语义,之后通过 XDoclet 工具对代码中 JavaDoc Tag 进行分析,自动生成与代码对应的配置文件(http://xdoclet.sourceforge.net/)。

XDoclet 提供了对 Hibernate 的支持,这样我们可以直接由 Java 代码生成 Hibernate 映射文件。

Middlegen: 从数据库中已有的表结构中生成 Hibernate 映射文件。当前版本是 2.1 可以去http://boss.bekk.no/boss/middlegen下载。

Page 13: 对象/关系映射— Hibernate

Hibernate 核心接口

Page 14: 对象/关系映射— Hibernate

Configuration

概述: Configuration 类负责管理 Hibernate 的配置信息。它包括如下内容: Hibernate运行的底层信息:数据库的 URL 、用户名、密码、 JDBC驱动类,数据库 Dialect, 数据库连接池等。 Hibernate 映射文件( *.hbm.xml )。

Hibernate 配置的两种方法: 属性文件( hibernate.properties )。调用代码: Configuration cfg = new Configuration(); Xml 文件( hibernate.cfg.xml )。调用代码: Configuration cfg = new Configuration().configure();

Page 15: 对象/关系映射— Hibernate

Configuration -例子 数据库连接的配置hibernate.dialect net.sf.hibernate.dialect.MySQLDialecthibernate.connection.driver_class com.mysql.jdbc.Driverhibernate.connection.url jdbc:mysql://localhost/hibernatehibernate.connection.username roothibernate.connection.password 数据库连接池的配置- DBCP ( App Server 连接池首选)hibernate.connection.provider_class

net.sf.hibernate.connection.DBCPConnectionProvider配置 DBCP 连接池 其它hibernate.show_sql truehibernate.jdbc.fetch_size 50hibernate.jdbc.batch_size 25

Page 16: 对象/关系映射— Hibernate

SessionFactory

概述:应用程序从 SessionFactory (会话工厂)里获得 Session(会话 ) 实例。它在多个应用线程间进行共享。通常情况下,整个应用只有唯一的一个会话工厂——例如在应用初始化时被创建。然而,如果你使用 Hibernate访问多个数据库,你需要对每一个数据库使用一个会话工厂。 会话工厂缓存了生成的 SQL 语句和 Hibernate 在运行时使用的映射元数据。 调用代码:SessionFactory sessionFactory = cfg.buildSessionFactory();

Page 17: 对象/关系映射— Hibernate

Session( 会话 )

概述: Session 不是线程安全的,它代表与数据库之间的一次操作,它的概念介于 Connection 和 Transaction 之间。 Session也称为持久化管理器,因为它是与持久化有关的操作接口。 Session通过 SessionFactory打开,在所有的工作完成后,需要关闭。 它与 Web 层的 HttpSession没有任何关系。 调用代码Session session = sessionFactory.openSession();

Page 18: 对象/关系映射— Hibernate

Transaction( 事务 )

概述: 它将应用代码从底层的事务实现中抽象出来——这可能是一个JDBC事务,一个 JTA 用户事务或者甚至是一个公共对象请求代理结构( CORBA ——) 允许应用通过一组一致的 API 控制事务边界。这有助于保持 Hibernate应用在不同类型的执行环境或容器中的可移植性。

调用代码: Transaction tx = session.beginTransaction();

注:使用 Hibernate 进行操作时(增、删、改)必须显示的调用Transaction (默认: autoCommit=false )。

Page 19: 对象/关系映射— Hibernate

Query

概述:Query (查询)接口允许你在数据库上执行查询并控制查询如何执行。查询语句使用 HQL或者本地数据库的 SQL 方言编写。 调用代码:Query query = session.createQuery(“from User”);

Page 20: 对象/关系映射— Hibernate

用户的例子持久化类- User.javapublic class User { private Long id; private String name; private Date birthday; private String email; public User(){ } public User(String

name,Date birthday,String email){

.....…Get/Set}

映射文件- User.hbm.xml

<hibernate-mapping>

<class name="com.test.um.User" table="TBL_USER">

<id name="id" column="ID">

<generator class="native"/>

</id>

<property name="name" column="NAME"/>

<property name="birthday" column="BIRTHDAY"/>

<property name="email" column="EMAIL"/>

</class>

</hibernate-mapping>

Page 21: 对象/关系映射— Hibernate

应用- UserTest.java

public void testCreate() throws Exception{ Configuration cfg = new Configuration(); cfg.addURL(UserTest.class.getResource("/com/test/um/User.hbm.xml")); SessionFactory sessionFactory = cfg.buildSessionFactory(); Session session = sessionFactory.openSession(); Transaction tx = session.beginTransaction(); SimpleDateFormat format = new SimpleDateFormat("yyyy-mm-dd"); User user = new User("Jack",format.parse("1980-04-12"),"[email protected]"); session.save(user); tx.commit(); assertNotNull(user.getId()); session.clear(); User user_2 = (User)session.get(User.class,user.getId()); assertNotNull(user_2); session.close(); }

Page 22: 对象/关系映射— Hibernate

应用- UserTest.java

保存用户: session.save(user);修改用户: session.update(user);保存或修改用户 :session.saveOrUpdate(user);删除用户: session.delete(user);删除所有用户: session.delete(“from User ”);

查询用户名为“ test” 的用户:Query query = session.createQuery("from User where user.name = :name");query.setParameter(“test",user.getName()); User findUser = (User) query.list().get(0);

Page 23: 对象/关系映射— Hibernate

三、 Hibernate 映射申明( Mapping declaration )

hibernate-mapping一、类层次。 class1 、主键。 id2 、基本类型。 property3 、自定义类。 many-to-one | one-to-one4 、集合。 set | list | map | array4.1 、 one-to-many4.2 、 many-to-many5 、子类。 subclass | joined-subclass6 、其它。 component | any等二、查询语句。 Query说明:一个 Hibernate-mapping 中可以同时定义多个类。 Query非常简单,主要是用来放置查询语句,便于对数据库查询的统一管理和优化。

Page 24: 对象/关系映射— Hibernate

hibernate-mapping

<hibernate-mapping schema="schemaName" (1) default-cascade="none|save-update" (2) auto-import="true|false" (3) package="package.name" (4) />( 1 )、 schema( 可选 ) :数据库 Schema Name( 2 )、 default-cascade (可选,默认为 none ):默认的级联风格( 3 )、 auto-import( 可选,默认为 true) :是否在查询中只使用类名。不用加 package名字。( 4 )、 package( 可选 ) ,如果该映射文件中定义的类名不包含

package ,则使用这里定义的 package 作为类名的前缀。

Page 25: 对象/关系映射— Hibernate

一、类层次 class

<class name="ClassName" (1) table="tableName" (2) mutable="true|false" (3)

dynamic-update="true|false" (4) dynamic-insert="true|false" (5) select-before-update="true|false" (6)

where="arbitrary sql where condition" (7) persister="PersisterClass" (8)/>

Page 26: 对象/关系映射— Hibernate

1 、主键 -id

<id name="propertyName" (1) type="typename" (2) column="column_name" (3) unsaved-value="any|none|null|id_value" (4)  <generator class="generatorClass"/></id>(1) 、 name ( 可选 ) :标识属性的名称。(2) 、 type( 可选 ) :标识 Hibernate 类型的名字。(3) 、 column( 可选-默认为属性名 ) :对应数据库表的主键字段的名字。(4) 、 unsaved-value( 可选-默认为 null) :这个值用来判断对象是否要保存。

Page 27: 对象/关系映射— Hibernate

1.1 主键生成策略 generator

generator主键生成器,每个主键都必须定义相应的主键生成策略。它用来为持久化类实例生成唯一的标识。 Hibernate 内置的主键生成策略 数据库提供的主键生成机制。 identity 、 sequence (序列) 。 外部程序提供的主键生成机制。 increment (递增) , hilo (高低位) , seqhilo (使用序列的高低位 ), uuid.hex( 使用了 IP地址

+JVM 的启动时间(精确到 1/4秒) + 系统时间 + 一个计数器值(在 JVM 中唯一) ) , uuid.string 。 其它。 native (本地), assigned (手工指定), foreign (外部引用)。

Page 28: 对象/关系映射— Hibernate

2 、基本类型- property

<property name="propertyName" (1) column="column_name" (2) type="typename" (3) update="true|false" (4) insert="true|false" (4) formula="arbitrary SQL expression" (5)/>(4) update, insert ( 可选 - 默认为 true) : 表明在用于 UPDATE 和 /或

INSERT 的 SQL 语句中是否包含这个字段。 (5) formula ( 可选 ): 一个 SQL 表达式,定义了这个计算

( computed ) 属性的值。计算属性没有和它对应的数据库字段。

Page 29: 对象/关系映射— Hibernate

3.1 、自定义类- many-to-one

<many-to-one name="propertyName" (1) column="column_name" (2) class="ClassName" (3) cascade="all|none|save-update|delete" (4) outer-join="true|false|auto" (5) property-ref="propertyNameFromAssociatedClass" (7)/>(3) class ( 可选 - 默认是通过反射得到属性类型 ): 关联的类的名字。 (4) cascade (级联) ( 可选 ): 指明哪些操作会从父对象级联到关联的对象。 (5) outer-join (外连接) ( 可选 - 默认为 自动 ) hibernate.use_outer_join (7) property-ref: ( 可选 ) 指定关联类的一个属性,这个属性将会和本外相对应。

Page 30: 对象/关系映射— Hibernate

例子 :User-Group

<class name=" com.test.hibernate .User" table="TBL_USER"><id name="id" column="userId"><generator class="native"/></id><many-to-one name=“group” column=“groupId” outer-join="false"/>

</class>

<class name=" com.test.hibernate .Group" table="TBL_GROUP"><id name="id" column="groupId"><generator class="native"/></id>

</class>

Page 31: 对象/关系映射— Hibernate

3.2 、自定义类- one-to-one

一对一关联:主键关联和惟一外键关联两种方式。例子: User-IdCard( 外键关联 )<class name=" com.test.hibernate .User" table="TBL_USER">

<id name="id" column="userId"><generator class="native"/></id><many-to-one name=“idCard” column=“idCardId” outer-join="false“ unique=“true”/>

</class>

<class name="com.test.hibernate.IdCard" table="TBL_IDCARD"><id name="id" column="idCardId"><generator class="native"/></id>

</class>

Page 32: 对象/关系映射— Hibernate

4 、集合- Set

<set name="propertyName" (1) table="table_name" (2) lazy="true|false" (3) inverse="true|false" (4) cascade="all|none|save-update|delete|all-delete-orphan" (5)order-by="column_name asc|desc" (6) where="arbitrary sql where condition" (7) outer-join="true|false|auto" (8)>

Page 33: 对象/关系映射— Hibernate

(1) name 集合属性的名称 (2) table (可选)目标关联数据库表(3) lazy ( 可选——默认为 false)允许延迟加载( lazy initialization )(4) inverse ( 可选——默认为 false) 标记有哪一方来维护关联关系(双向关联中使用) 。(5) cascade ( 可选——默认为 none) 让操作级联到子实体 (6) order-by ( 可选 , 仅用于 jdk1.4) 指定表的字段 ( 一个或几个 )再加

上 asc或者 desc( 可选 ), 定义Map,Set 和 Bag 的迭代顺序 (7) where ( 可选 ) 指定任意的 SQL where条件(8) outer-join( 可选 -默认为 auto) 是否使用外联接

Page 34: 对象/关系映射— Hibernate

4.1 、 one-to-many

概念:一对多关联直接连接两个类对应的表 ,而没有中间集合表。( 实现了一个一对多的关系模型,例如: User-Address)

这里的 Java集合必须满足下面的语义:map,set 或 list 中不能包含 null值一个被包含的实体的实例只能被包含在一个集合的实例中

<one-to-many class="ClassName"/>

(1) class( 必须 ):被关联类的名称。

Page 35: 对象/关系映射— Hibernate

例子 (one-to-many) : User-Address

<class name="com.test.hibernate.User" table="TBL_USER"><id name="id" column="userId"><generator

class="native"/></id><set name="addresses" lazy="true" cascade="all">

<key column="addressId"/><one-to-many class="com.test.hibernate.Address"/>

</set></class>

<class name="com.test.hibernate.Address" table="TBL_ADDRESS"> <id name="id" column="addressId"> <generator class="native"/></id></class>

Page 36: 对象/关系映射— Hibernate

4.2 、 many-to-many

<many-to-many column="column_name" (1) class="ClassName" (2) outer-join="true|false|auto" (3)/>(1) column( 必需 ): 中间映射表中,关联目标表的关联字段(2) class ( 必需 ): 类名,关联目标类(3) outer-join ( 可选 - 默认为 auto)

<key column="column_name"/> (1)(1) column( 必需 ):当前表的关联字段

Page 37: 对象/关系映射— Hibernate

例子 (many to many) : student-trainClass

<class name="com.test.hibernate.Student"><id name="id" column="userId"><generator class="native"/></id><set name="trainClasses" lazy="true" cascade="save-update">

<key column="studentId"/><many-to-many class="com.test.hibernate.TrainClass"

column="trainClassId"/></set>

</class><class name="com.test.hibernate.TrainClass"

table="TBL_TRAIN_CLASS"><id name="id" column="trainClassId"><generator class="native"/></id>

</class>

Page 38: 对象/关系映射— Hibernate

5 、继承 继承实现的三中策略 单表继承。每棵类继承树使用一个表 (table per class hierarchy) 具体表继承。每个子类一个表 (table per subclass) 类表继承。每个具体类一个表 (table per concrete class) (有一些限制) 单表继承<discriminator column="discriminator_column" (1) type="discriminator_type" (2)/><subclass>

Page 39: 对象/关系映射— Hibernate

例子 ( 继承 ) : user-student

<class name="com.test.hibernate.User" table="TBL_USER"><id name="id" column="userId">

<generator class="native"/></id><discriminator type="string" column="inherit"/>

<subclass name="com.test.hibernate.Student"><property name="number"

column="studentNumber"/></subclass>

</class>

Page 40: 对象/关系映射— Hibernate

双向关联 概念:双向关联允许通过关联的任一端访问另外一端。在

Hibernate 中 , 支持两种类型的双向关联。 一对多( one-to-many ), Set或者 bag值在一端 , 单独值 (非集合 ) 在另外一端 。 多对多( many-to-many ),两端都是 set 或 bag值。

Page 41: 对象/关系映射— Hibernate

例子 ( 双向关联 ) : group-user

<class name="com.test.hibernate.Group" table="TBL_GROUP"><id name="id" column="groupId"><generator class="native“></id><set name="users" lazy="true" cascade="save-update" inverse="true"> <key column="groupId"/><one-to-many class="com.test.hibernate.User"/></set>

</class>

<class name="com.test.hibernate.User" table="TBL_USER"><id name="id" column="userId"><generator class="native"/></id><many-to-one name="group" column="groupId" outer-join="false"/>

</class>

Page 42: 对象/关系映射— Hibernate

例子:从 Java 代码看 group-user 双向关联的 inverse

概念: inverse 用来标识双向关联的关联关系由哪一端维护。默认inverse 的值为 false ,由主动方负责维护关联关系;如果设为true ,则由反向一端维护关联关系。

用例:我们假设已经有一个 Group 类的实例: adminGroup ,现在我们要新增一个用户,并且将用户分配到 adminGroup 中。 inverse=“false” ,由主动方 Group 负责维护 group-user 的关联关系 .User user = new User(“Jak”);adminGroup.getUsers.add(user);session.save(user); session.update(group); inverse=“true” ,由 Group 的反向段 User 负责维护关联关系。User user = new User(“Jak”);user .setGroup(adminGroup); session.save(user);

Page 43: 对象/关系映射— Hibernate

四、持久化对象的状态 瞬时对象 (Transient Objects) :使用 new 操作符初始化的对象不是立刻就持久的。它们的状态是瞬时的,也就是说它们没有任何跟数据库表相关联的行为,只要应用不再引用这些对象(不再被任何其它对象所引用),它们的状态将会丢失,并由垃圾回收机制回收。 持久化对 (Persist Objects) :持久实例是任何具有数据库标识的实例。它有持久化管理器 Session 统一管理,持久实例是在事务中进行操作的——它们的状态在事务结束时同数据库进行同步。当事务提交时,通过执行 SQL 的 INSERT 、 UPDATE 和 DELETE 语句把内存中的状态同步到数据库中。 离线对象 (Detached Objects) : Session 关闭之后,持久化对象就变为离线对象。离线表示这个对象不能再与数据库保持同步,它们不再受 Hibernate管理。

Page 44: 对象/关系映射— Hibernate

持久化对象的生命周期( lifecycle )

Page 45: 对象/关系映射— Hibernate

Hibernate脏数据字段捡入 检索一个用户,并将它的用户名更改为“ Mary”Session session = sessionFactory.openSession();Transaction tx = session.beginTransaction();User user = (User) session.get(User.class, userId);user.setName("Mary");tx.commit();session.close();

Page 46: 对象/关系映射— Hibernate

持久化对象必须唯一 一个 Session 中不能同时存在两个 ID 相同的持久化对象例如: id 为 userId 的 user_1 对象已经存在 Session 中,这时如果

Session 中试图产生一个 user_2 对象!!Session session = sessionFactory.openSession();Transaction tx = session.beginTransaction();User user_1 = (User)session.get(User.class,userId);User user_2 = new User(userId,”Mary”);session.update(user_2);最后将会产生异常: net.sf.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session解决办法: 使用 evict () 方法将 user_1 实例从 session 中去除。 session.evict(user_1);

Page 47: 对象/关系映射— Hibernate

五、 Hibernate 查询 概述:数据查询与检索是 Hibernate 中的一个亮点。相对其他

ORM 实现而言, Hibernate 提供了灵活多样的查询机制。 标准化对象查询 (Criteria Query) :以对象的方式进行查询,将查询语句封装为对象操作。优点:可读性好,符合 Java 程序员的编码习惯。缺点:不够成熟,不支持投影( projection )或统计函数

( aggregation ) Hibernate 语言查询( Hibernate Query Language , HQL ):它是完全面向对象的查询语句,查询功能非常强大,具备继承、多态和关联等特性 。 Hibernate官方推荐使用 HQL 进行查询。 Native SQL Queries (原生 SQL 查询):直接使用数据库提供的

SQL 方言进行查询。

Page 48: 对象/关系映射— Hibernate

例子:标准化对象查询 (Criteria Query)

简单例子:查询用户名以“ J” 开头的所有用户。Criteria criteria = session.createCriteria(User.class);

criteria.add(Expression.like("name","J%")); List users = criteria.list();

Page 49: 对象/关系映射— Hibernate

Hibernate 语言查询( Hibernate Query Language , HQL )

HQL 用面向对象的方式生成 SQL 以类和属性来代替表和数据列 支持多态 支持各种关联 减少了 SQL 的冗余 HQL 支持所有的关系数据库操作 连接( joins,包括 Inner/outer/full joins ),笛卡尔积 (cartesian products) 投影( projection ) 聚合( Aggregation , max, avg )和分组( group ) 排序( Ordering ) 子查询( Subqueries ) SQL函数( SQL function calls )

Page 50: 对象/关系映射— Hibernate

例子: Hibernate 语言查询( Hibernate Query Language , HQL )

简单例子:查询用户名以“ J” 开头的所有用户。Query query = session.createQuery(

"from User user where user.name like 'J%'"); List users = query.list(); 复杂例子:从 User 和 Group 中查找属于“ admin” 组的所有用户。

Query query = session.createQuery(“from User user where user.group.name=‘admin’”);

如果用传统的 SQL则查询语句如下:select user.userId as userId, user.name as name, user.groupId as groupId,

user.idCardId as idCardId from TBL_USER user, TBL_GROUP group where (group.groupName='admin' and user.groupId=group.groupId)

Page 51: 对象/关系映射— Hibernate

六、 Hibernate 最佳实践( Best Practices )

1 、使用 Configuration 装载映射文件时,不要使用绝对路径装载。最好的方式是通过 getResourceAsStream() 装载映射文件,这样Hibernate会从 classpath 中寻找已配置的映射文件。

2 、 SessionFactory 的创建非常消耗资源,整个应用一般只要一个SessionFactory就够了,只有多个数据库的时候才会使用多个SessionFactory 。

3 、在整个应用中, Session 和事务应该能够统一管理。( Spring 为Hibernate 提供了非常好的支持)

4 、将所有的集合属性配置设置为懒加载( lazy=”true” )。在hibernate2.x版本中, lazy默认值是“ false”, 但 hibernate3.x已经将lazy 的默认改为“ true” 了。

Page 52: 对象/关系映射— Hibernate

Hibernate 最佳实践( Best Practices )

5 、在定义关联关系时,集合首选 Set ,如果集合中的实体存在重复,则选择 List (在定义配置文件时,可以将 List 定义为 bag ),数组的性能最差。6 、在一对多的双向关联中,一般将集合的 inverse 属性设置为 true ,让集合的对方维护关联关系。例如: Group-User ,由 User 来维护

Group 和 User 的关联关系。7 、 HQL 子句本身大小写无关,但是其中出现的类名和属性名必须注意大小写区分。8 、在非分布式架构中,不需要使用 DTO 来向上层传输数据。直接使

用 POJO 的 Entity就可以了。9 、如果要精通 Hibernate ,熟练掌握关系数据库理论和 SQL 是前提条件。

Page 53: 对象/关系映射— Hibernate

Hibernate 资源 官方网站: http://www.hibernate.org 国内网站: http://www.hibernate.org.cn Java新视线论坛: http://forum.hibernate.org 《 Hibernate 中文开发指南》作者夏昕( http://www.redsaga.com/) 《深入浅出 Hibernate》作者:夏昕 曹晓钢 唐勇( http://www.china-pub.com/computers/common/info.asp?id=24500 ) 《 Hibernate in Action 》 作 者 : Christian Bauer and Gavin

King ( http://www.javafan.net/ 可下载) 《 Hibernate: A Developer's Notebook》作者: James Elliott

结束,谢谢 !