ThinkSSL🔒 一键申购 5分钟快速签发 30天无理由退款 购买更放心 广告
# 5.1.3\. class 你可以使用`class`元素来定义一个持久化类: ``` <class name="ClassName" table="tableName" discriminator-value="discriminator_value" mutable="true|false" schema="owner" catalog="catalog" proxy="ProxyInterface" dynamic-update="true|false" dynamic-insert="true|false" select-before-update="true|false" polymorphism="implicit|explicit" where="arbitrary sql where condition" persister="PersisterClass" batch-size="N" optimistic-lock="none|version|dirty|all" lazy="true|false" entity-name="EntityName" check="arbitrary sql check condition" rowid="rowid" subselect="SQL expression" abstract="true|false" node="element-name" /> ``` | ![1](img/1.png) | `name` (可选): 持久化类(或者接口)的Java全限定名。 如果这个属性不存在,Hibernate将假定这是一个非POJO的实体映射。 | |:--- |:--- | | ![2](img/2.png) | `table` (可选 - 默认是类的非全限定名): 对应的数据库表名。 | | ![3](img/3.png) | `discriminator-value` (可选 - 默认和类名一样): 一个用于区分不同的子类的值,在多态行为时使用。它可以接受的值包括 `null` 和 `not null`。 | | ![4](img/4.png) | `mutable` (可选,默认值为`true`): 表明该类的实例是可变的或者不可变的。 | | ![5](img/5.png) | `schema` (可选): 覆盖在根`&lt;hibernate-mapping&gt;`元素中指定的schema名字。 | | ![6](img/6.png) | `catalog` (可选): 覆盖在根`&lt;hibernate-mapping&gt;`元素中指定的catalog名字。 | | ![7](img/7.png) | `proxy` (可选): 指定一个接口,在延迟装载时作为代理使用。 你可以在这里使用该类自己的名字。 | | ![8](img/8.png) | `dynamic-update` (可选, 默认为 `false`): 指定用于`UPDATE` 的SQL将会在运行时动态生成,并且只更新那些改变过的字段。 | | ![9](img/9.png) | `dynamic-insert` (可选, 默认为 `false`): 指定用于`INSERT`的 SQL 将会在运行时动态生成,并且只包含那些非空值字段。 | | ![10](img/10.png) | `select-before-update` (可选, 默认为 `false`): 指定Hibernate除非确定对象真正被修改了(如果该值为true-译注),否则_不会_执行SQL `UPDATE`操作。在特定场合(实际上,它只在一个瞬时对象(transient object)关联到一个 新的session中时执行的update()中生效),这说明Hibernate会在`UPDATE` 之前执行一次额外的SQL `SELECT`操作,来决定是否应该执行 `UPDATE`。 | | ![11](img/11.png) | `polymorphism(多态)` (可选, 默认值为 `implicit (隐式)` ): 界定是隐式还是显式的使用多态查询(这只在Hibernate的具体表继承策略中用到-译注)。 | | ![12](img/12.png) | `where` (可选) 指定一个附加的SQL`WHERE` 条件, 在抓取这个类的对象时会一直增加这个条件。 | | ![13](img/13.png) | `persister` (可选): 指定一个定制的`ClassPersister`。 | | ![14](img/14.png) | `batch-size` (可选,默认是`1`) 指定一个用于 根据标识符(identifier)抓取实例时使用的"batch size"(批次抓取数量)。 | | ![15](img/15.png) | `optimistic-lock(乐观锁定)` (可选,默认是`version`): 决定乐观锁定的策略。 | | (16) | `lazy` (可选): 通过设置`lazy="false"`, 所有的延迟加载(Lazy fetching)功能将被全部禁用(disabled)。 | | (17) | `entity-name` (可选,默认为类名): Hibernate3允许一个类进行多次映射( 前提是映射到不同的表),并且允许使用Maps或XML代替Java层次的实体映射 (也就是实现动态领域模型,不用写持久化类-译注)。 更多信息请看[第 4.4 节 “动态模型(Dynamic models)”](../Text/pr01_split_000.html "4.4\. 动态模型(Dynamic models)") and [第 18 章 _XML映射_](../Text/pr01_split_000.html "第 18 章 XML映射")。 | | (18) | `check` (可选): 这是一个SQL表达式, 用于为自动生成的schema添加多行(multi-row)约束_检查_。 | | (19) | `rowid` (可选): Hibernate可以使用数据库支持的所谓的ROWIDs,例如: Oracle数据库,如果你设置这个可选的`rowid`, Hibernate可以使用额外的字段`rowid`实现快速更新。ROWID是这个功能实现的重点, 它代表了一个存储元组(tuple)的物理位置。 | | (20) | `subselect` (可选): 它将一个不可变(immutable)并且只读的实体映射到一个数据库的 子查询中。当你想用视图代替一张基本表的时候,这是有用的,但最好不要这样做。更多的介绍请看下面内容。 | | (21) | `abstract` (可选): 用于在`&lt;union-subclass&gt;`的继承结构 (hierarchies)中标识抽象超类。 | 若指明的持久化类实际上是一个接口,这也是完全可以接受的。 之后你可以用元素`&lt;subclass&gt;`来指定该接口的实际实现类。 你可以持久化任何_static_(静态的)内部类。 你应该使用标准的类名格式来指定类名,`比如:Foo$Bar`。 不可变类,`mutable="false"`不可以被应用程序更新或者删除。 这可以让Hibernate做一些小小的性能优化。 可选的`proxy`属性允许延迟加载类的持久化实例。 Hibernate开始会返回实现了这个命名接口的CGLIB代理。当代理的某个方法被实际调用的时候, 真实的持久化对象才会被装载。参见下面的“用于延迟装载的代理”。 _Implicit_ (隐式)的多态是指,如果查询时给出的是任何超类、该类实现的接口或者该类的 名字,都会返回这个类的实例;如果查询中给出的是子类的名字,则会返回子类的实例。 _Explicit_ (显式)的多态是指,只有在查询时给出明确的该类名字时才会返回这个类的实例; 同时只有在这个`&lt;class&gt;`的定义中作为`&lt;subclass&gt;` 或者`&lt;joined-subclass&gt;`出现的子类,才会可能返回。 在大多数情况下,默认的`polymorphism="implicit"`都是合适的。 显式的多态在有两个不同的类映射到同一个表的时候很有用。(允许一个“轻型”的类,只包含部分表字段)。 `persister`属性可以让你定制这个类使用的持久化策略。 你可以指定你自己实现 `org.hibernate.persister.EntityPersister`的子类,你甚至可以完全从头开始编写一个 `org.hibernate.persister.ClassPersister`接口的实现, 比如是用储存过程调用、序列化到文件或者LDAP数据库来实现。 参阅`org.hibernate.test.CustomPersister`,这是一个简单的例子 (“持久化”到一个`Hashtable`)。 请注意`dynamic-update`和`dynamic-insert`的设置并不会继承到子类, 所以在`&lt;subclass&gt;`或者`&lt;joined-subclass&gt;`元素中可能 需要再次设置。这些设置是否能够提高效率要视情形而定。请用你的智慧决定是否使用。 使用`select-before-update`通常会降低性能。如果你重新连接一个脱管(detache)对象实例 到一个`Session`中时,它可以防止数据库不必要的触发update。 这就很有用了。 如果你打开了`dynamic-update`,你可以选择几种乐观锁定的策略: * `version(版本检查)` 检查version/timestamp字段 * `all(全部)` 检查全部字段 * `dirty(脏检查)`只检察修改过的字段 * `none(不检查)`不使用乐观锁定 我们_非常_强烈建议你在Hibernate中使用version/timestamp字段来进行乐观锁定。 对性能来说,这是最好的选择,并且这也是唯一能够处理在session外进行操作的策略(例如: 在使用`Session.merge()`的时候)。 对Hibernate映射来说视图和表是没有区别的,这是因为它们在数据层都是透明的( 注意:一些数据库不支持视图属性,特别是更新的时候)。有时你想使用视图,但却不能在数据库 中创建它(例如:在遗留的schema中)。这样的话,你可以映射一个不可变的(immutable)并且是 只读的实体到一个给定的SQL子查询表达式: ``` <class name="Summary"> <subselect> select item.name, max(bid.amount), count(*) from item join bid on bid.item_id = item.id group by item.name </subselect> <synchronize table="item"/> <synchronize table="bid"/> <id name="name"/> ... </class> ``` 定义这个实体用到的表为同步(synchronize),确保自动刷新(auto-flush)正确执行, 并且依赖原实体的查询不会返回过期数据。`&lt;subselect&gt;`在属性元素 和一个嵌套映射元素中都可见。