Hibernate7-Hibernate映射文件(*.hbm.xml)

在前面的这篇文章中我们提到过Hibernate映射文件,也说了一些基本的属性和标签,现在我们就详细的说一下Hibernate映射文件。

理论

    通过映射文件Hibernate可以理解类与数据库表之间的对应关系,例如某个类对应某个表,某个属性对应某个表中字段;并且Hibernate也可以理解表和表之间的关系。
    在运行时Hibernate将自动生成sql语句。
    我们可以在一个映射文件中,使用<class></class>子节点来定义多个类。

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 name="cc.ibadboy.hibernate.hibernate2.entity.User" table="User_test">
        <id name="id" type="java.lang.Integer" column="id">
            <generator class="native"></generator>
        </id>
        <property name="name" type="java.lang.String" column="name" length="50" not-null="true"/>
        <property name="pwd" type="java.lang.String"  column="pwd" length="50" not-null="true"/>
    </class>
</hibernate-mapping>

如果我们hibernate-mapping中配置了很多class子节点,而这些类都是在同一个包下,那么我们可以配置package属性如下

<hibernate-mapping package="cc.ibadboy.hibernate.hibernate2.entity">
    <class name="User" table="User_test">
        <id name="id" type="java.lang.Integer" column="id">
            <generator class="native"></generator>
        </id>
        <property name="name" type="java.lang.String" column="name" length="50" not-null="true"/>
        <property name="pwd" type="java.lang.String"  column="pwd" length="50" not-null="true"/>
    </class>
</hibernate-mapping>

这就说明我这个映射文件中的所有类都在cc.ibadboy.hibernate.hibernate2.entity包下。

class节点属性

1.schema (可选):
    覆盖在根<hibernate-mapping>
元素中指定的schema名字。
2.catalog (可选):
    覆盖在根<hibernate-mapping>元素中指定的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,就相当于将<property/>元素的update属性设置为false一样,表示整个实例都不能被更新。用栗子说话,我们将mutable属性这是为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风格的属性, 为每一个实例包含唯一的标识。<id>元素定义了该属性到数据库表主键字段的映射。
1.unsaved-value (可选 – 默认为一个切合实际(sensible)的值):
    一个特定的标识属性值,用来标志该实例是刚刚创建的,尚未保存。 这可以把这种实例和从以前的session中装载过 但未再次持久化的实例区分开来。
2.access (可选 – 默认为property):
    Hibernate用来访问属性值的策略。如果 name属性不存在,会认为这个类没有标识属性。

3.name (可选):
    标识属性的名字。就是你映射对象中用做记录主键的属性。
4.column (可选 – 默认为属性名):
    主键字段的名字。就是你表中主键字段名。
5.type (可选):
    属性值一般为你属性的数据类型,例如type=”java.lang.Integer”。

class节点中generator节点

    可选的<generator>子元素是一个Java类的名字(class属性值就是java类名,注意:此类必须实现IdentifierGenerator接口), 用来为该持久化类的实例生成唯一的标识。如果这个生成器实例需要某些配置值或者初始化参数, 用<param>元素来传递。栗子

<id name="id" column="cat_id">
        <generator class="org.hibernate.id.TableHiLoGenerator">
                <param name="table">uid_table</param>
                <param name="column">next_hi_value_column</param>
        </generator>
</id>

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()之前为对象分配一个标示符。这是<generator>元素没有指定时的默认生成策略。
10.select
    通过数据库触发器选择一些唯一主键的行并返回主键值来分配一个主键。
11.foreign
    使用另外一个相关联的对象的标识符。通常和<one-to-one>联合起来使用。
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 (可选 – 默认为属性名字):
    对应的数据库字段名。 也可以通过嵌套的<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语句。

注意

    我上面每个节点属性做了区分,没有详细解释的放在上面做了详细解释放在下面,并用换行作为区分,详细解释的请大家一定一定一定要记住,虽然未必能用得到。

配图
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,588评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,456评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,146评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,387评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,481评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,510评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,522评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,296评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,745评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,039评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,202评论 1 343
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,901评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,538评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,165评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,415评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,081评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,085评论 2 352

推荐阅读更多精彩内容

  • Hibernate中配置主要分为两种:一种包含了Hibernate与数据库的基本连接信息,在Hibernate工作...
    FTOLsXD阅读 2,037评论 0 10
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,646评论 18 139
  • 1. 简介 1.1 什么是 MyBatis ? MyBatis 是支持定制化 SQL、存储过程以及高级映射的优秀的...
    笨鸟慢飞阅读 5,490评论 0 4
  • 本文中我们介绍并比较两种最流行的开源持久框架:iBATIS和Hibernate,我们还会讨论到Java Persi...
    大同若鱼阅读 4,305评论 4 27
  • “你的目光所及之处,都会有我的存在,哪里有挨饿的穷人,哪里就有我。” 这段台词来自本片《愤怒的葡萄》,如今看来,颇...
    会飞的清蒸鱼阅读 325评论 0 0