首页 > 代码库 > Hibernate的映射文件

Hibernate的映射文件

映射文件的结构和属性

一个映射文件(mapping file)由一个根节点<hibernate-mapping>和多个<class>节点组成,

首先看看根节点<hibernate-mapping>支持什么属性:

1 <hibernate-mapping
2          schema="schemaName"                               (1)
3          catalog="catalogName"                             (2)
4          default-cascade="cascade_style"                   (3)
5          default-access="field|property|ClassName"         (4)
6          default-lazy="true|false"                         (5)
7          auto-import="true|false"                          (6)
8          package="package.name"                            (7)
9  />

这8个属性都是可选的,下面解释几个重要的属性,

default-lazy:延迟加载,默认为true,Hibernate通过默认加载提升性能,通常建议设置为true。在后面的配置属性和集合映射时也可以指定lazy值

auto-import:是否允许查询语句中使用非全限定类名,默认为true,当一个映射文件中有两个持久化类,包名不同,类名相同时,需要设置auto-import为false才能区分。

package:设置该值之后,映射文件就不再需要指定全限定类名

 

再看看<class>标签支持什么样的属性,

 1 <class
 2         name="ClassName"                                   (1)
 3         table="tableName"                                  (2)
 4         discriminator-value="discriminator_value"          (3)
 5         mutable="true|false"                               (4)
 6         schema="owner"                                     (5)
 7         catalog="catalog"                                  (6)
 8         proxy="ProxyInterface"                             (7)
 9         dynamic-update="true|false"                        (8)
10         dynamic-insert="true|false"                        (9)
11         select-before-update="true|false"                  (10)
12         polymorphism="implicit|explicit"                   (11)
13         where="arbitrary sql where condition"              (12)
14         persister="PersisterClass"                         (13)
15         batch-size="N"                                     (14)
16         optimistic-lock="none|version|dirty|all"           (15)
17         lazy="true|false"                                  (16)
18         entity-name="EntityName"                           (17)
19         check="arbitrary sql check condition"              (18)
20         rowxml:id="rowid"                                  (19)
21         subselect="SQL expression"                         (20)
22         abstract="true|false"                              (21)
23         node="element-name"
24 />

 

一对<class>就代表一个持久化实体类,即数据库中的表,在<class>元素下,通常还会有<id>和<property>子元素,用来构成表的各个字段,<id>通常用来映射主键,<property>则用来映射普通字段,另外还可以通过<set> <map>等映射集合字段,下面一一讲解。

映射主键(<id...>

Hibernate建议为持久化类定义一个标识属性(identifier property),如private int id, 标识属性映射数据库底层的主键字段(primary key column )。在映射文件中,标识属性用<id>表示,<id>标签支持以下属性:

 1 <id
 2         name="propertyName"                                (1)
 3         type="typename"                                    (2)
 4         column="column_name"                               (3)
 5         unsaved-value="null|any|none|undefined|id_value"   (4)
 6         access="field|property|ClassName">                 (5)
 7         node="element-name|@attribute-name|element/@attribute|."
 8 
 9         <generator class="generatorClass"/>
10 </id>

unsaved-value:指定刚创建尚未保存时的标识属性值,用来区分已经加载到session但未再次持久化的实例,Hibernate 3中已经不需要指定这个属性。

上面几个属性通常只需要指定 name, type, column这三个属性,在泛型中,type属性也不需要指定,Hibernate会通过反射获取字段类型

在Hibernate中,提供了一个逻辑主键生成器,在映射文件中通过<id>元素的子元素<generator>表示,可以为每个持久化类生成唯一逻辑主键,

主键生成器<generator>的class属性支持以下值,代表不同种类的主键生成器策略,

1 <generator class="increment|identity|sequence|hilo|seqhilo|uuid|guid|native|assigned|select|foreign" />

其中最常用的identiry,适合DB2,MySQL, MSSQL等支持自增长字段的数据库,可以返回long, short, int等。

sequence,适合DB2,Oracle等。

映射普通属性(<property...>

<property>标签支持以下属性,

 1 <property
 2         name="propertyName"                                (1)
 3         column="column_name"                               (2)
 4         type="typename"                                    (3)
 5         update="true|false"                                (4)
 6         insert="true|false"                                (4)
 7         formula="arbitrary SQL expression"                 (5)
 8         access="field|property|ClassName"                  (6)
 9         lazy="true|false"                                  (7)
10         unique="true|false"                                (8)
11         not-null="true|false"                              (9)
12         optimistic-lock="true|false"                       (10)
13         generated="never|insert|always"                    (11)
14         node="element-name|@attribute-name|element/@attribute|."
15         index="index_name"
16         unique_key="unique_key_id"
17         length="L"
18         precision="P"
19         scale="S"
20 />

通常情况下只需指定name, column, type的值, 另外部分属性解释如下

update和insert:输入属性值不需要Hibernate生成,则指定为false

formula=(sql):直接写SQL获取数据,括号不能少

lazy:是否延迟加载,默认为false

下面演示一下formula的用法,

如果我们在实体类Person.java中有一个普通属性 private String fullContent;

1 private String fullContent;

在映射文件中,这个属性的值是通过formula的方式获取的,则映射文件应该这么写,

1 ...
2 <property name="fullContent" formula="(select concat(p.name,p.age) from person_inf p where p.person_id = person_id)" />
3 ...

这样,我们在测试类中如果要获取这个属性值的话,就会取formula的值

1 Person p = (Person)sess.get(Person.class, 3);
2 System.out.println(p.getFullContent());

上面的例子只是得到一个实体类的属性字段值,但是在数据库层面并没有生成这个字段,

要想数据库也生成这个字段,则要通过<property>标签的generated属性来指定, 例如

1 ...
2 <property name="fullContent" column="full_content" type="string" generated="insert" />
3 ...

同时,需要有一个数据库的触发器配合使用才能实现上面的功能,

 1 drop database test;
 2 create database test;
 3 use test;
 4 create table person_inf
 5 (
 6 id auto_increment primary key,
 7 title varchar(255) not null,
 8 content varchar(255)
 9 full_content varchar(255)
10 );
11 DELEMITER |
12 create trigger t_full_content_gen BEFORE INSERT ON person_inf
13     FOR EACH ROW BEGIN
14         set person_inf.full_content=concat(person_inf.title, person_inf.content);
15     END;
16 |
17 DELIMITER ;

先执行上面的SQL脚本,然后才执行java程序,另外需要将hibernate.cfg.xml的hbm2ddl.auto改为update,避免重建数据库时丢失触发器。

之后,便可以像上面那样访问这个属性了,

1 Person p = (Person)sess.get(Person.class, 3);
2 System.out.println(p.getFullContent());

 

Hibernate的映射文件