首页 > 代码库 > 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的映射文件