在前面的这篇文章中我们提到过Hibernate映射文件,也说了一些基本的属性和标签,现在我们就详细的说一下Hibernate映射文件。
理论
通过映射文件Hibernate可以理解类与数据库表之间的对应关系,例如某个类对应某个表,某个属性对应某个表中字段;并且Hibernate也可以理解表和表之间的关系。
在运行时Hibernate将自动生成sql语句。
我们可以在一个映射文件中,使用
子节点来定义多个类。
Hibernate-mapping根节点属性
1.catalog (可选):
数据库catalog的名称。
2.default-cascade (可选 – 默认为 none):
默认的级联风格。
3.default-access (可选 – 默认为 property):
Hibernate用来访问所有属性的策略。可以通过实现PropertyAccessor接口 自定义。
4.default-lazy (可选 – 默认为 true):
指定了未明确注明lazy属性的Java属性和集合类, Hibernate会采取什么样的默认加载风格。
5.auto-import (可选 – 默认为 true):
指定我们是否可以在查询语言中使用非全限定的类名(仅限于本映射文件中的类)。
6.schema (可选):
数据库schema的名称。如果你使用的是反响工程工具来生成hibernate映射文件需要注意。以oracle数据库为例,假设你的机器上有一个为admin1用户,你将表建立在admin1用户中,用反向工程生成映射文件后做了一段时间的开发,现在你换了另一台电脑来做临时开发,这是你将表建立在临时电脑的admin2用户中,如果你的schema属性没有改的话,就会出现异常,提示你说表不存在。此时你只需要将schema属性改为admin2,或去掉schema属性即可。
7.package (可选):
指定一个包前缀,如果在映射文档中没有指定全限定的类名, 就使用这个作为包名。例如我们现在配置的映射文件是这样的
如果我们hibernate-mapping中配置了很多class子节点,而这些类都是在同一个包下,那么我们可以配置package属性如下
这就说明我这个映射文件中的所有类都在cc.ibadboy.hibernate.hibernate2.entity
包下。
class节点属性
1.schema (可选):
覆盖在根
元素中指定的schema名字。
2.catalog (可选):
覆盖在根
3.proxy (可选):
指定一个接口,在延迟装载时作为代理使用。 你可以在这里使用该类自己的名字。
4.polymorphism(多态) (可选, 默认值为 implicit (隐式) ):
界定是隐式还是显式的使用多态查询(这只在Hibernate的具体表继承策略中用到-译注)。
5.where (可选) :
指定一个附加的SQLWHERE 条件, 在抓取这个类的对象时会一直增加这个条件。
6.persister (可选):
指定一个定制的ClassPersister。
7.optimistic-lock(乐观锁定) (可选,默认是version):
决定乐观锁定的策略。
8.check (可选):
这是一个SQL表达式, 用于为自动生成的schema添加多行(multi-row)约束检查。
9.rowid (可选):
Hibernate可以使用数据库支持的所谓的ROWIDs,例如: Oracle数据库,如果你设置这个可选的rowid, Hibernate可以使用额外的字段rowid实现快速更新。ROWID是这个功能实现的重点, 它代表了一个存储元组(tuple)的物理位置。
10.subselect (可选):
它将一个不可变(immutable)并且只读的实体映射到一个数据库的 子查询中。当你想用视图代替一张基本表的时候,这是有用的,但最好不要这样做。更多的介绍请看下面内容。
11.abstract (可选):
用于在的继承结构 (hierarchies)中标识抽象超类。
12.name (可选):
持久化类(或者接口)的Java全限定名。 如果这个属性不存在,Hibernate将假定这是一个非POJO的实体映射。虽然说是可选,但是在我心中,此属性已经成为了必须属性。
13.table (可选 – 默认是类的非全限定名):
对应的数据库表名。虽然说是可选,但是在我心中,此属性已经成为了必须属性。
14.dynamic-update (可选, 默认为 false):
指定用于UPDATE 的SQL将会在运行时动态生成,并且只更新那些改变过的字段。举个栗子如果我们不设置此属性,执行一下代码查看效果
User user = session.get(User.class, 3);
user.setPwd("admin-pwd");
session.update(user);
运行结果如下
update User_test set name=?, pwd=? where id=?
可以看出,我们只是要修改pwd字段的值,而hibernate生成的sql语句也将我们name字段也给更改了(没有设置name属性就是默认属性值),但是我们只需要修改pwd字段值,不需要做额外操作,所以我们需要设置dynamic-update属性为true。再次修改一下pwd属性值,执行代码后可以看出sql如下
update User_test set pwd=? where id=?
15.dynamic-insert (可选, 默认为 false):
指定用于INSERT的 SQL 将会在运行时动态生成,并且只包含那些非空值字段。这个与dynamic-update属性是一样的道理。
16.batch-size (可选,默认是1) :
指定一个用于 根据标识符(identifier)抓取实例时使用的”batch size”(批次抓取数量)。
17.discriminator-value (可选 – 默认和类名一样):
一个用于区分不同的子类的值,在多态行为时使用。它可以接受的值包括 null 和 not null。
18.lazy (可选):
通过设置lazy=”false”, 所有的延迟加载(Lazy fetching)功能将被全部禁用(disabled)。还记得我们的load方法吗?他默认是延时加载的只有用到的时候才会加载对吧。而如果将此属性设置为false那么,他就会变的和get方法一样,不管你用没用到都会加载。
19.mutable (可选,默认值为true):
表明该类的实例是可变的或者不可变的。如果设置为false,就相当于将
User user = session.load(User.class, 3);
user.setPwd("456456456456");
session.update(user);
执行以上代码可以看出,没有发送update语句。
20.select-before-update (可选, 默认为 false):
指定Hibernate除非确定对象真正被修改了(如果该值为true-译注),否则不会执行SQL UPDATE操作。在特定场合(实际上,它只在一个瞬时对象(transient object)关联到一个 新的session中时执行的update()中生效),这说明Hibernate会在UPDATE 之前执行一次额外的SQL SELECT操作,来决定是否应该执行 UPDATE。说了这么多其实理解起来很简单,我们在对游离对象进行更新的时候,我们可以设置此属性值为true,hibernate会先进行查询判断数据库中的记录与我游离对象是相同的话就不会执行update语句,如果不一样则会执行update语句。但是如果设置此属性为true,那么总是会发送select语句进行查询,所以不建议设置。
class节点属性
被映射的类必须定义对应数据库表主键字段。大多数类有一JavaBeans风格的属性, 为每一个实例包含唯一的标识。
元素定义了该属性到数据库表主键字段的映射。
1.unsaved-value (可选 – 默认为一个切合实际(sensible)的值):
一个特定的标识属性值,用来标志该实例是刚刚创建的,尚未保存。 这可以把这种实例和从以前的session中装载过 但未再次持久化的实例区分开来。
2.access (可选 – 默认为property):
Hibernate用来访问属性值的策略。如果 name属性不存在,会认为这个类没有标识属性。
3.name (可选):
标识属性的名字。就是你映射对象中用做记录主键的属性。
4.column (可选 – 默认为属性名):
主键字段的名字。就是你表中主键字段名。
5.type (可选):
属性值一般为你属性的数据类型,例如type=”java.lang.Integer”。
class节点中generator节点
可选的
子元素是一个Java类的名字(class属性值就是java类名,注意:此类必须实现IdentifierGenerator接口), 用来为该持久化类的实例生成唯一的标识。如果这个生成器实例需要某些配置值或者初始化参数, 用元素来传递。栗子
uid_table
next_hi_value_column
hibernate提供的内置主键生成器
1.increment
用于为long, short或者int类型生成 唯一标识。只有在没有其他进程往同一张表中插入数据时才能使用。 在集群下不要使用。
2.identity
对DB2,MySQL, MS SQL Server, Sybase和HypersonicSQL的内置标识字段提供支持。 返回的标识符是long, short 或者int类型的。
3.sequence
在DB2,PostgreSQL, Oracle, SAP DB, McKoi中使用序列(sequence), 而在Interbase中使用生成器(generator)。返回的标识符是long, short或者 int类型的。
4.hilo
使用一个高/低位算法高效的生成long, short 或者 int类型的标识符。给定一个表和字段(默认分别是 hibernate_unique_key 和next_hi)作为高位值的来源。 高/低位算法生成的标识符只在一个特定的数据库中是唯一的。
5.seqhilo
使用一个高/低位算法来高效的生成long, short 或者 int类型的标识符,给定一个数据库序列(sequence)的名字。
6.uuid
用一个128-bit的UUID算法生成字符串类型的标识符, 这在一个网络中是唯一的(使用了IP地址)。UUID被编码为一个32位16进制数字的字符串。
7.guid
在MS SQL Server 和 MySQL 中使用数据库生成的GUID字符串。
8.native
根据底层数据库的能力选择identity, sequence 或者hilo中的一个。
9.assigned
让应用程序在save()之前为对象分配一个标示符。这是
元素没有指定时的默认生成策略。
10.select
通过数据库触发器选择一些唯一主键的行并返回主键值来分配一个主键。
11.foreign
使用另外一个相关联的对象的标识符。通常和
联合起来使用。
12.sequence-identity
一种特别的序列生成策略,使用数据库序列来生成实际值,但将它和JDBC3的getGeneratedKeys结合在一起,使得在插入语句执行的时候就返回生成的值。目前为止只有面向JDK 1.4的Oracle 10g驱动支持这一策略。注意,因为Oracle驱动程序的一个bug,这些插入语句的注释被关闭了。
property节点
1.lazy (可选 – 默认为 false):
指定 指定实例变量第一次被访问时,这个属性是否延迟抓取(fetched lazily)( 需要运行时字节码增强)。
2.optimistic-lock (可选 – 默认为 true):
指定这个属性在做更新时是否需要获得乐观锁定(optimistic lock)。 换句话说,它决定这个属性发生脏数据时版本(version)的值是否增长。
3.generated (可选 – 默认为 never):
表明此属性值是否实际上是由数据库生成的。
4.name:
属性的名字,以小写字母开头。对象的属性名。
5.column (可选 – 默认为属性名字):
对应的数据库字段名。 也可以通过嵌套的
6.type (可选):
一个Hibernate类型的名字。hibernate类型是java类型与sql数据库类型的桥梁,如果没有没有设置此类型,则hibernate会通过反射来获取属性类型,然后找到对应的hibernate类型。也就是说你可以写java的全类名,也可以写hibernate类型,例如type=”string”,小写s开头的很明显不是java类型。
7.access (可选 – 默认值为 property):
Hibernate用来访问属性值的策略。也就是说hibernate会使用set和get方法访问;如果设置为field则会使用反射访问。
8.unique (可选):
使用DDL为该字段添加唯一的约束。 同样,允许它作为property-ref引用的目标。说的很明白,就是添加唯一约束。
9.not-null (可选):
使用DDL为该字段添加可否为空(nullability)的约束。如果设置为true,说明改字段不能为空。
10.update, insert (可选 – 默认为 true) :
表明用于UPDATE 和/或 INSERT 的SQL语句中是否包含这个被映射了的字段。这二者如果都设置为false 则表明这是一个“外源性(derived)”的属性,它的值来源于映射到同一个(或多个) 字段的某些其他属性,或者通过一个trigger(触发器)或其他程序生成。说了这么多,其实就是在说,如果设置为false此字段不能更新,或添加。
11.formula (可选):
一个SQL表达式,定义了这个计算属性的值。这里要用sql语句,并且属于子查询所以要用小括号扩起来,hibernate会动态生成sql语句后,自动拼接上formula属性中的sql语句。
注意
我上面每个节点属性做了区分,没有详细解释的放在上面做了详细解释放在下面,并用换行作为区分,详细解释的请大家一定一定一定要记住,虽然未必能用得到。