【Hibernate总结系列】....hbm.xml配置
在Hibernate中,各表的映射文件….hbm.xml可以通过工具生成,例如在使用MyEclipse开发时,它提供了自动生成映射文件的工具。本节简单的讲述一下这些配置文件的配置。
8 session 和sessionfactory的比较:
sessionFactory它实现了线程安全问题,一个应用程序就一个sessionFactory;提供了序列接口;
session不 是线程安全的
一个请求提供一个session,所有的请求共享一个sessionfactory;
以下的程序都是在sessionfactory中进行的
10 有种写法:static{ }这样的写法叫做静态语句化;建立的时候要捕获异常。
11 hibernation的三种对象状态;
Transient:瞬时状态 persistent:持久状态 detached:托管状态(脱机管理)
用到的方法有commit()托管(提交)和rollback()回滚;
瞬时状态:内存中的对象在数据库中没有与之对应的记录,也就是没有持久化标识(主键),并且没有纳入session的管理。那么此时对象(o)没有发出任何sql语句,也就是对象(o)和关系(r)没有联动,
(判断对象和数据库是否有关联的标准是对象是否具有持久化标识”主键”)
持久状态:内存的对象在数据库中有与之对应的记录,也就是有持久化标识,并且纳入了session的管理,那么对象就会发出sql语句,此时对象与关系就发生实时的联动。
托管状态:内存中的对象与数据库有与之对应的记录,但是没有纳入session的管理,那么对象就不会发出sql语句,也就是说对象和关系没有发生联动;注:在托管状态下可以发出update语句;
在这当中有个变态函数:saveOrUpdate();
上述已经完成了添加、保存和修改。下来就开始了显示的语句用到的是 get();
User=(user)session.get(user.class, 1)
此方法的意思是session.get(class类型,序列化接口);同时不管查询几次只发出一条select语句;
注:在get执行的时候首先搜索缓存中是否存在持久化标识为1的对象,如果有就直接取出对象,如果没有的话;就发送sql语句进行查询;这里显示所用的就是一级缓存(也就是session级别的 );
(1) 在将get函数改为load函数时候就会出现代理模式
代理模式:用load去代理查询,它的意思就是用的时候就发(查询语句)不用的时候就不发、
Load属于延迟加载,默认不发送sql语句,只有当对象调用的时候才发sql语句;
(2) load找不到对象它会显示对象找不到,而get找不到他会显示空指针。
注:Hibernate的映射中不能将数据库中的字段设置为null,因为hibernate不会将null解析出来;
会抛出异常来;
12 删除数据:在托管状态下,先装载对象数据再去删除;也就是先查询,在去删除;删除后的数据字段就
是瞬时状态;下来的话其他的字段就变成了托管状态了;接着要变为持久化状态的话就就要去load
或update一下;不能用save因为就造成了主键冲突;
注:在hibernate中不允许有两个持久化状态指向同一字段。这样也会造成主键冲突;
Session.merge()。merge函数用法是不改变状态:不会从托管状态变为持久化状态;
HQL语句差不多和SQL语句相似
Hibernian的基本映射;
自动生成表单机制:首先实例化configuration对象。实现此功能的类是:org.hibernate.tool.hbm2ddl 下的 SchemaExport 里的create方法;就可以了; 用log4j生成数据库的日志文件;先创建表在创建序列
1. Doctype
所有的XML映射都需要定义如上所示的doctype。DTD可以从上述URL中获取,也可以从hibernate-x.x.x/src/net/sf /hibernate目录中、或hibernate.jar文件中找到。Hibernate总是会首先在它的classptah中搜索DTD文件。如果你 发现它是通过连接Internet查找DTD文件,就对照你的classpath目录检查XML文件里的DTD声明。
2. hibernate-mapping
这个元素包括一些可选的属性。schema和catalog属性,指明了这个映射所连接(refer)的表所在的schema和/或catalog名称。 假若指定了这个属性,表名会加上所指定的schema和catalog的名字扩展为全限定名。假若没有指定,表名就不会使用全限定名。 default-cascade指定了未明确注明cascade属性的Java属性和集合类Hibernate会采取什么样的默认级联风格。auto- import属性默认让我们在查询语言中可以使用非全限定名的类名。
<hibernate-mapping
schema="schemaName" (1)
catalog="catalogName" (2)
default-cascade="cascade_style" (3)
default-access="field|property|ClassName" (4)
default-lazy="true|false" (5)
auto-import="true|false" (6)
package="package.name" (7)
/>
(1) schema (可选): 数据库schema的名称。
(2) catalog (可选): 数据库catalog的名称。
(3) default-cascade (可选 - 默认为 none): 默认的级联风格。
(4) default-access (可选 - 默认为 property): Hibernate用来访问所有属性的策略。可以通过实现PropertyAccessor接口 自定义。
(5) default-lazy (可选 - 默认为 true): 指定了未明确注明lazy属性的Java属性和集合类, Hibernate会采取什么样的默认加载风格。
(6) auto-import (可选 - 默认为 true): 指定我们是否可以在查询语言中使用非全限定的类名(仅限于本映射文件中的类)。
(7) package (可选): 指定一个包前缀,如果在映射文档中没有指定全限定的类名,就使用这个作为包名。
5.1.3. class
你可以使用class元素来定义一个持久化类:
<class
name="ClassName" (1)
table="tableName" (2)
discriminator-value="discriminator_value" (3)
mutable="true|false" (4)
schema="owner" (5)
catalog="catalog" (6)
proxy="ProxyInterface" (7)
dynamic-update="true|false" (8)
dynamic-insert="true|false" (9)
select-before-update="true|false" (10)
polymorphism="implicit|explicit" (11)
where="arbitrary sql where condition" (12)
persister="PersisterClass" (13)
batch-size="N" (14)
optimistic-lock="none|version|dirty|all" (15)
lazy="true|false" (16)
entity-name="EntityName" (17)
check="arbitrary sql check condition" (18)
rowid="rowid" (19)
subselect="SQL expression" (20)
abstract="true|false" (21)
node="element-name"
/>
(1) name (可选): 持久化类(或者接口)的Java全限定名。如果这个属性不存在,Hibernate将假定这是一个非POJO的实体映射。
(2) table (可选 - 默认是类的非全限定名): 对应的数据库表名。
(3) discriminator-value (可选 - 默认和类名一样): 一个用于区分不同的子类的值,在多态行为时使用。它可以接受的值包括 null 和 not null。
(4) mutable (可选,默认值为true): 表明该类的实例是可变的或者不可变的。
(5) schema (可选): 覆盖在根<hibernate-mapping>元素中指定的schema名字。
(6) catalog (可选): 覆盖在根<hibernate-mapping>元素中指定的catalog名字。
(7) proxy (可选): 指定一个接口,在延迟装载时作为代理使用。 你可以在这里使用该类自己的名字。
(8) dynamic-update (可选, 默认为 false): 指定用于UPDATE 的SQL将会在运行时动态生成,并且只更新那些改变过的字段。
(9) dynamic-insert (可选, 默认为 false): 指定用于INSERT的 SQL 将会在运行时动态生成,并且只包含那些非空值字段。
(10) select-before-update (可选, 默认为 false): 指定Hibernate除非确定对象真正被修改了(如果该值为true-译注),否则不会执行SQL UPDATE操作。在特定场合(实际上,它只在一个瞬时对象(transient object)关联到一个新的session中时执行的update()中生效),这说明Hibernate会在UPDATE 之前执行一次额外的SQL SELECT操作,来决定是否应该执行 UPDATE。
(11) polymorphism(多态) (可选, 默认值为 implicit (隐式) ): 界定是隐式还是显式的使用多态查询(这只在Hibernate的具体表继承策略中用到-译注)。
(12) where (可选) 指定一个附加的SQLWHERE 条件, 在抓取这个类的对象时会一直增加这个条件。
(13) persister (可选): 指定一个定制的ClassPersister。
(14) batch-size (可选,默认是1) 指定一个用于根据标识符(identifier)抓取实例时使用的"batch size"(批次抓取数量)。
(15) optimistic-lock(乐观锁定) (可选,默认是version): 决定乐观锁定的策略。
(16) lazy (可选): 通过设置lazy="false", 所有的延迟加载(Lazy fetching)功能将被全部禁用(disabled)。
(17) entity-name (可选,默认为类名): Hibernate3允许一个类进行多次映射(前提是映射到不同的表),并且允许使用Maps或XML代替Java层次的实体映射(也就是实现动态领域模型,不用写持久化类-译注)。
(18) check (可选): 这是一个SQL表达式,用于为自动生成的schema添加多行(multi-row)约束检查。
(19) rowid (可选): Hibernate可以使用数据库支持的所谓的ROWIDs,例如: Oracle数据库,如果你设置这个可选的rowid, Hibernate可以使用额外的字段rowid实现快速更新。ROWID是这个功能实现的重点,它代表了一个存储元组(tuple)的物理位置。
(20) subselect (可选): 它将一个不可变(immutable)并且只读的实体映射到一个数据库的子查询中。当你想用视图代替一张基本表的时候,这是有用的,但最好不要这样做。更多的介绍请看下面内容。
(21) abstract (可选): 用于在<union-subclass>的继承结构(hierarchies)中标识抽象超类。
5.1.4. id
被映射的类必须定义对应数据库表主键字段。大多数类有一个JavaBeans风格的属性,为每一个实例包含唯一的标识。<id> 元素定义了该属性到数据库表主键字段的映射。
<id
name="propertyName" (1)
type="typename" (2)
column="column_name" (3)
unsaved-value="null|any|none|undefined|id_value" (4)
access="field|property|ClassName" (5)
length="L" (6)
<generator class="generatorClass"/>
</id>
(1) name (可选): 标识属性的名字。
(2) type (可选): 标识Hibernate类型的名字。(如果没配置,hibernate将会自动转化成相应的数据库类型)
(3) column (可选 - 默认为属性名): 主键字段的名字。
(4) unsaved-value (可选 - 默认为一个切合实际(sensible)的值): 一个特定的标识属性值,用来标志该实例是刚刚创建的,尚未保存。这可以把这种实例和从以前的session中装载过(可能又做过修改--译者注)但未再次 持久化的实例区分开来。
(5) access (可选 - 默认为property): Hibernate用来访问属性值的策略。
(6)length="L"指定长度
8. Generator
可选的<generator>子元素是一个Java类的名字,用来为该持久化类的实例生成唯一的标识。如果这个生成器实例需要某些配置值或者初始化参数,用<param>元素来传递。
<id name="id" type="long" 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>
所有的生成器都实现org.hibernate.id.IdentifierGenerator接口。这是一个非常简单的接口;某些应用程序可以选择提供他们自己特定的实现。当然, Hibernate提供了很多内置的实现。
下面是一些内置生成器的快捷名字:
increment
用于为long, short或者int类型生成唯一标识。只有在没有其他进程往同一张表中插入数据时才能使用。在集群下不要使用。
identity
对DB2,MySQL, MS SQL Server, Sybase和HypersonicSQL的内置标识字段提供支持。返回的标识符是long, short 或者int类型的。
sequence
在DB2,PostgreSQL, Oracle, SAP DB, McKoi中使用序列(sequence),而在Interbase中使用生成器(generator)。返回的标识符是long, short或者 int类型的。
hilo
使用一个高/低位算法高效的生成long, short 或者 int类型的标识符。给定一个表和字段(默认分别是 hibernate_unique_key 和next_hi)作为高位值的来源。高/低位算法生成的标识符只在一个特定的数据库中是唯一的。
seqhilo
使用一个高/低位算法来高效的生成long, short 或者 int类型的标识符,给定一个数据库序列(sequence)的名字。
uuid
用一个128-bit的UUID算法生成字符串类型的标识符,这在一个网络中是唯一的(使用了IP地址)。UUID被编码为一个32位16进制数字的字符串。
guid
在MS SQL Server 和 MySQL 中使用数据库生成的GUID字符串。
native
根据底层数据库的能力选择identity, sequence 或者hilo中的一个。
assigned
让应用程序在save()之前为对象分配一个标示符。这是 <generator>元素没有指定时的默认生成策略。手动分配主键的时候要设置成它
select
通过数据库触发器选择一些唯一主键的行并返回主键值来分配一个主键。
foreign
使用另外一个相关联的对象的标识符。通常和<one-to-one>联合起来使用。
9. property
<property>元素为类定义了一个持久化的,JavaBean风格的属性。
<property
name="propertyName" (1)
column="column_name" (2)
type="typename" (3)
update="true|false" (4)
insert="true|false" (4)
formula="arbitrary SQL expression" (5)
access="field|property|ClassName" (6)
lazy="true|false" (7)
unique="true|false" (8)
not-null="true|false" (9)
optimistic-lock="true|false" (10)
generated="never|insert|always" (11)
node="element-name|@attribute-name|element/@attribute|."
index="index_name"
unique_key="unique_key_id"
length="L"
precision="P"
scale="S"
/>
(1) name: 属性的名字,以小写字母开头。
(2) column (可选 - 默认为属性名字): 对应的数据库字段名。也可以通过嵌套的<column>元素指定。
(3) type (可选): 一个Hibernate类型的名字。
(4) update, insert (可选 - 默认为 true) : 表明用于UPDATE 和/或 INSERT 的SQL语句中是否包含这个被映射了的字段。这二者如果都设置为false 则表明这是一个“外源性(derived)”的属性,它的值来源于映射到同一个(或多个)字段的某些其他属性,或者通过一个trigger(触发器)或其 他程序生成。
(5) formula (可选): 一个SQL表达式,定义了这个计算(computed)属性的值。计算属性没有和它对应的数据库字段。
(6) access (可选 - 默认值为 property): Hibernate用来访问属性值的策略。
(7) lazy (可选 - 默认为 false): 指定指定实例变量第一次被访问时,这个属性是否延迟抓取(fetched lazily)( 需要运行时字节码增强)。
(8) unique (可选): 使用DDL为该字段添加唯一的约束。 同样,允许它作为property-ref引用的目标。
(9) not-null (可选): 使用DDL为该字段添加可否为空(nullability)的约束。
(10) optimistic-lock (可选 - 默认为 true): 指定这个属性在做更新时是否需要获得乐观锁定(optimistic lock)。换句话说,它决定这个属性发生脏数据时版本(version)的值是否增长。
(11) generated (可选 - 默认为 never): 表明此属性值是否实际上是由数据库生成的。
typename可以是如下几种:
Hibernate基本类型名(比如:integer, string, character,date, timestamp, float, binary, serializable, object, blob)。
一个Java类的名字,这个类属于一种默认基础类型 (比如: int, float,char, java.lang.String, java.util.Date, java.lang.Integer, java.sql.Clob)。
一个可以序列化的Java类的名字。
一个自定义类型的类的名字。(比如: com.illflow.type.MyCustomType)。
基本值类型(Hibernate内建立自己的类型,从java转化成数据库类型)
string
从java.lang.String 到 VARCHAR (或者 Oracle的 VARCHAR2)的映射。
date, time, timestamp
从java.util.Date和其子类到SQL类型DATE, TIME 和TIMESTAMP (或等价类型)的映射。
calendar, calendar_date
从java.util.Calendar 到SQL 类型TIMESTAMP和 DATE(或等价类型)的映射。
big_decimal, big_integer
从java.math.BigDecimal和java.math.BigInteger到NUMERIC (或者 Oracle 的NUMBER类型)的映射。
locale, timezone, currency
从java.util.Locale, java.util.TimeZone 和java.util.Currency 到VARCHAR (或者 Oracle 的VARCHAR2类型)的映射. Locale和 Currency 的实例被映射为它们的ISO代码。TimeZone的实例被影射为它的ID。
class
从java.lang.Class 到 VARCHAR (或者 Oracle 的VARCHAR2类型)的映射。Class被映射为它的全限定名。
binary
把字节数组(byte arrays)映射为对应的 SQL二进制类型。
text
把长Java字符串映射为SQL的CLOB或者TEXT类型。
serializable
把可序列化的Java类型映射到对应的SQL二进制类型。你也可以为一个并非默认为基本类型的可序列化Java类或者接口指定Hibernate类型serializable。
clob, blob
JDBC 类 java.sql.Clob 和 java.sql.Blob的映射。某些程序可能不适合使用这个类型,因为blob和clob对象可能在一个事务之外是无法重用的。(而且, 驱动程序对这种类型的支持充满着补丁和前后矛盾。)