Hibernate参考手册

对象操作

实体状态

        自由状态……实体对象在内存中自由存在,与数据库中的记录没有任何关联,处理自由状态的实例可以通过Session的save方法转换成持久状态。

        持久状态……实体对象处于由Hibernate框架所管理的状态,持久状态的对象其变更将由Hibernate固化到数据库中,持久对象对应数据库中的一条记录。

        游离状态……处于持久状态的实例,其关联的会话已经关闭,则此实例处于 游离状态。 游离状态的实例可以通过Session的 update方法再次和一个会话关联。

        游离状态和自由状态实例的区别是自由状态的实例与数据库缺乏对应关系,而游离状态的实例包含对应数据库记录的主键值。        

实体身份识别

        从数据库的角度,包括Hibernate本身对于拥有同样主键值的实体对象则认为他们是相同的。在持久层之外,对象是否等价在业务逻辑层可能有另外的含 义,往往有一些特定的数据实体判定规则,这可以通过重写equals和hashCode方法实现。

脏数据检查

        脏数据检查策略一般有两种方式:

        数据对象监控:可以借助动态代理或CGLIB拦截设值方法,一旦设值方法被调用,则将其标记为脏状态。

        数据版本比对:持久层框架维持数据对象的最新版本,当数据提交时将提交数据和此版本进行比对,如果发生变化则将其同步到数据库相应的库表。

        Hibernate采用数据版本比对方式,Hibernate会话保存所有与当前会话关联实体的当前实例和原始状态信息,可以参见SessionImpl 的内部类EntityEntry。

Load/Get

       这两个操作的功能都是从数据库中加载一个实例,两者的区别是前者如果没有找到匹配数据将抛出异常,后者将返回null。

List/Iterate

       这两个操作的功能 都是从数据库中加载多个实例,两者的区别是Iterate方法会先从会话中或者二级缓存中获取,而list方法会直接查询数据库,如果需要的数据在缓存中 存在,iterate可以提供更好的性能,相反的情况下iterate方法会更慢,它会首先执行查询仅从数据库中获取标识符,然后再分别查询初始化实例。

Update/Merge

       这两个操作都支持分离实例的重新关联。如果会话中已经包含同样标识符的实例,update方法会抛出异常,merge方法会合并更改再重新关联。

Flush

       Flush方法的主要功能是同步内存对象和数据库,flush操作缺省发生在一些查询操作之前,事务提交时或者调用flush方法时。
       显式调用flush方法并不能保证立即执行数据库同步,Hibernate保证Query.list方法不会返回过时或错误数据。
       可以通过Session.setFlushMode改变缺省行 为,不至于太频繁。FlushMode定义了三种不同的刷新方式:提交时刷新,自动刷新,不刷新(除非显式调用flush方法)。
       提交时刷新可能会导致查询操作获取过时数据。

级联

       Hibernate 会话的基本操作,包括persist,merge,saveOrUpdate等都有相应的级联样式设置,如果你希望关联集合针对某个操作进行级联设置,可 以在映射文件中设置,示例如下:

xml 代码
  1. <one-to-one name="person" cascade="persist,delete,lock"/>  

       缺省的级联设置是none,表示任何操作都不支持级联。

       级联通常用在在一对一和一对多关系中。

继承映射

单表映射

      概述: 使用一张表映射整个继承树,需要一个类别字段区分一个数据行具体对应哪个类。 

      优点:有很好的查询性能,不需要进行表连接。

       缺点:有数据冗余。子类的字段无法建立非空约束。

类表映射

       概述:每个类对应一张表。子类表只包含扩展属性,子类表和父类表通过外键关联。

       优点:领域模型和数据库之间的关系非常明了。

       缺点: 查询时需要多表之间的内连接或左外连接操作。字段在层次中任何上下移动的重构都会导致数据库更改。

具体表映射(UNION)

       概述:每个具体类对应一张表,包含所有的字段。使用union-class进行定义。

       优点:与具体表映射(隐式多态)相比,支持多态查询。

       缺点:具体类不支持标识生成器,标识生成器在所有的具体类中共享。如果某个属性在超类中进行映射,则其列名在所有的子类表中必须相同。 

具体表映射(隐式多态)

        概述:每个具体类对应一张表,包含所有的字段。

       优点:查询子类时不需要关联。

        缺点:如果父类字段发生变动,所有的子类表必须同时进行修改。超类上的一次查找需要检查所有表,这会导致多次数据库访问或特殊连接操作。不支持多态外连接 抓取数据。不支持多态一对一和一对多关联。

集合映射    

       Hibernate要求实体的集合字段必须声明为接口类型,当持久化实体时,Hibernate会使用自己的集合实现。因此假定使用HashSet初始化 实体的集合字段,经过持久化后得到的集合字段并不是HashSet的实例,如果进行转型将发生错误。

有序/无序

       Hibernate支持Set,Bag,Map三种无序集合,List是有序集合,这里所谓的有序无序是指Hibernate持久化过程中,是否保持数据集合中的记录排列顺序。

可配置属性

       Lazy……缺省为true,表示不加载关联的集合。
       Cascade……缺省为none,表示不级联操作集合。
       Fetch……缺省为select,可以设置为join使用连接检索模式。
       optimistic-lock……缺省为true,表示集合状态的改变会导致拥有集合的实体的版本增加,如果是一对多关联,通常设置为false。

Inverse

       缺省为false,如果为true,表示关联由另一端管理。

Sort/Order-by

      Sort/Order-by属性用来设置集合排序,前者表示排序基于内存操作的,后者表示数据库检索时进行排序,通过指定SQL语句的order by部分来实现。

外键信息

      使用key元素进行定义。

元素类型

      使用element和composite-element定义值类型,使用one-to-many和many-to-many定义实体类型。

索引集合

      除SET和BAG外,其他集合都需要指定集合表中的索引列,LIST和ARRAY使用list-index元素定义,MAP集合使用map-key/composite-map-key或map-key-many-to-many定义。

List/Bag

      如果希望使用list声明集合字段,而表中又没有索引列,那么可以使用bag元素定义映射,bag元素不具备list的有序特性。

Bag/idBag

      Bag 类型是Hibernate自定义集合类型,实现一个允许包含重复元素的Set,因为Bag集合为无序集,且允许出现重复元素,这出现一个问题,当删除某个 元素时如何定位待删除记录?目前的实现方式是先将表中原有的集合数据全部删除,再将现有数据逐条插入,显然这种方式的性能是极其低下的。
      idBag对此进行了扩展,提供一个collection-id元素用来配置id字段,根据此id,Hibernate可以准确定位库表记录,从而实现高效的数据操作。

事务/并发

      Hibernate直接使用JDBC和JTA资源的事务语义,没有添加额外的锁机制。SessionFactory是线程安全的,可以被所有的应用线程共享。Session是线程不安全的,通常用于单个请求,单个会话或单个工作单元。

      通常不管读写数据,数据库交互都应该发生在事务语义中。

      在多用户的C/S应用程序中,最通用的模式是基于请求的会话,使用单个的数据库事务服务整个客户请求,在WEB企业应用程序中,数据库事务跨越用户交互是无法接受的。

      会话会缓存每个处理持久状态的实例,这意味着如果保持会话打开一段比较长的时间,可能导致内存不足,也可能导致过时数据。一个解决方法是调用clear和evict方法管理会话,但是更应该考虑使用存储过程处理大数据量操作。

乐观并发访问

      支持高并发性和高扩展性的唯一方式是使用版本的乐观并发控制。版本检查使用版本号或时间戳来检查更新。Hibernate提供三种方式使用乐观并发控制。
      手动版本检查:每次数据库操作发生在一个新的会话中,开发者有责任在操作之前加载所有的持久化实例,手动执行版本检查。这种方式是最低效的,类似于实体EJB的方式。

      扩 展会话方式的自动版本检查:Hibernate基于一次交互创建一个会话,在每次执行刷新时检查实例的版本,如果检测到并发更改将抛出异常,由开发人员负 责捕获和处理异常。这种方式是最有效的,应用不必关心版本检查,不必重新关联分离状态的实例,也不必在每次数据库事务前重新加载所有的实例。

      分离状态实例的自动版本检查:应用可以操纵一个分离状态的实例的属性,这个实例是在另一个会话加载的,然后再和一个新的会话重新关联(通过调用update或saveOrUpdate方法),当新会话刷新时会自动执行版本检查。

      自 定义版本检查:也可以通过设置属性或集合的optimistic-lock值为false禁止自动版本检测,也可以设置Class映射的 optimistic-lock属性为all,通过比较实例的所有字段进行版本检查,有时候并发更改只要没有发生叠加也是允许的,这可以通过设置 optimistic-lock属性为dirty实现。

悲观锁

      通常情况下用户不需要共太多时间关心锁策略,通过对JDBC连接指定隔离级别可以让数据库负责这些工作,然而高级用户可能需要获取排他锁或启动新事务时重新获取锁。
      Hibernate总是使用数据库的锁机制,LockMode类定义了Hibernate可以获得的锁级别,这可以通过Session的lock/load方法和Query的setLockMode方法进行操纵。

性能优化

抓取策略

      抓取策略是指Hibernate如何检索关联对象,抓取策略可以通过映射设置,也可以在HQL和规则查询中重写。Hibernate支持以下几种抓取策略:
            join……使用外连接抓取。
            Select……使用一个单独的查询语句抓取关联数据。
            Subselect……
            Batch……select抓取的优化,通过指定一个主键或外键列表使用一个单独的查询语句中进行抓取。

      同时Hibernate区分如下几种抓取方式:
            Immediate……立即加载
            Lazy……懒加载,需要时加载整个集合
            Extra-lazy……按需加载集合中的单个元素,尽量不同时加载整个集合,适用于集合很大的情况。
            Proxy……当激活关联对象的某个方法而不是取值方法时检索单值关联。
            No-proxy……实例变量被访问时检索单值关联,相比proxy策略,这种方式少一些懒加载,要求构建二进制字节码,很少使用。
            Lazy attribute……当实例变量被访问时检索单值关联或属性,这种方式要求构建二进制字节码,很少使用。

       以上分别决定什么时候加载以及怎样加载,缺省情况下Hibernate使用lazy select抓取关联集合,使用lazy proxy抓取单值关联。

       如果设置hibernate.default_batch_fetch_size,,Hibernate将使用Batch抓取策略。

      使用select策略通常会导致n+1次查询,这可以通过使用join策略解决,可以在hql和criteria中调用setFetchMode设置检索策略。


      有时候我们需要在会话关闭时,初始化代理和集合,这可以通过Hibernate的initialize和isInitializied方法实现。
有时候你不想初始化一个大的集合,而只是需要集合的一个子集或者集合的大小 ,这时候可以使用集合过滤器,比如要获取集合的大小:

  1. s.createFilter( lazyCollection, "").setFirstResult(0).setMaxResults(10).list();  
 缓存

        Hibernate数据缓存分为两个层次,Session级别的内部缓存,SessionFactory级别的二级缓存。

        内部缓存正常情况下由Hibernate自动维护,如果需要手工干预,可以通过如下方法完成:

                evict方法从当前缓存中移除某个实例

                contains会话中是否包含某个实例

                clear用来清除会话。

        引入二级缓存必须考虑一些问题:

                数据库是否与其他应用共享,如果需要通常必须放弃二级缓存的使用。

                应用是否需要部署在集群环境中,此时必须考虑是否需要引入分布式缓存。

                应该对哪些数据进行缓存。

        如果满足以下条件,则可以考虑二级缓存:

                数据不会被第三方应用修改。

                数据大小在可接受范围。

                数据更新频率较低。

                同一数据可能会被系统频繁调用。

                非关键数据。

        Hibernate缺省使用EHCache作为其二级缓存,SessionFactory提供几个方法用来有效管理二级缓存。

                evict清除某个类

                evictCollection清除某个集合。

CacheMode用来控制会话如何和二级缓存进行交互,包括NORMAL,READ,WRITE和REFRESH选项。

        可以使用Statistics API查询二级缓存,示例如下:

java 代码 
  1. Map cacheEntries = sessionFactory.   
  2. .getSecondLevelCacheStatistics(   
  3. .getEntries();  

        可以通过设置 hibernate.cache.use_query_cache属性为true启用查询缓存,查询缓存应该总是和二级缓存一起使用。此设置将创建两个缓 存区域,一个缓存查询结果,一个缓存对查询表的最近更新的时间戳。大部分查询不会受益于查询缓存,因此缺省设置为false。可以调用 Query.setSacheable方法手动缓存查询结果。

集合性能

       所有的索引集合list,array,map都有一个主键包含key和index列,主键可以很容易的被索引,更新删除时也可以很快定位,因此这种集合通常是最有效的。

       Set集合有一个主键包含key列和element列,对某些情况,这种集合是低效的,特别是组合元素或者大文本字段,因为数据库可能不能有效索引比较复杂的主键。

       IdBag通常是最有效的。

       Bag通常是最坏的选择,因为允许重复值,没有索引列,没有主键可以定义,Hibernate没有办法区别重复行,只有通过完全删除和完全重建来响应任何改变,这是相当低效的。

       List/map/Idbag/set针对更新操作是最有效的,包括添加/更新/删除。

       Set应该Hibernate应用中最常用的集合,因为关 系数据库模型中set集合语义是最自然的,然而在设计良好的应用程序中,我们看到大部分集合是inverse设置为true的一对多关联,这种情况下, bag通常是最有效的集合,因为添加元素到bag和list不需要执行抓取操作(set则不然),此时执行类似下面的代码将会更快

java 代码
  1. Parent p = (Parent) sess.load(Parent.class, id);   
  2. Child c = new Child();   
  3. c.setParent(p);   
  4. p.getChildren().add(c); //no need to fetch the collection!   
  5. sess.flush();  
性能监听

       Statistics接口提供三种类别的统计信息:
              Sesssion使用相关的,比如打开的会话数目,检索的JDBC连接数目。
              实体,集合,查询和缓存相关的全局信息。
              特定实体,集合,查询和缓存区域的详细信息。

       具体细节可以参考Statistics, EntityStatistics, CollectionStatistics,
SecondLevelCacheStatistics和QueryStatistics的API文档,示例如下:

java 代码
  1. Statistics stats = HibernateUtil.sessionFactory.getStatistics();   
  2. double queryCacheHitCount = stats.getQueryCacheHitCount();   
  3. double queryCacheMissCount = stats.getQueryCacheMissCount();   
  4. double queryCacheHitRatio =   
  5. queryCacheHitCount / (queryCacheHitCount + queryCacheMissCount);   
  6. log.info("Query Hit ratio:" + queryCacheHitRatio);   
  7. EntityStatistics entityStats =   
  8. stats.getEntityStatistics( Cat.class.getName() );   
  9. long changes =   
  10. entityStats.getInsertCount()   
  11. + entityStats.getUpdateCount()   
  12. + entityStats.getDeleteCount();   
  13. log.info(Cat.class.getName() + " changed " + changes + "times" );  
1. 在Tomcat中快速上手 1.1. 开始Hibernate之旅 1.2. 第一个持久化类 1.3. 映射cat 1.4. 与Cat同乐 1.5. 结语 2. 架构(Architecture) 2.1. 概况(Overview) 2.2. 实例状态 2.3. JMX整合 2.4. 对JCA的支持 3. 配置 3.1. 可编程的配置方式 3.2. 获得SessionFactory 3.3. JDBC连接 3.4. 可选的配置属性 3.4.1. SQL方言 3.4.2. 外连接抓取(Outer Join Fetching) 3.4.3. 二进制流 (Binary Streams) 3.4.4. 二级缓存与查询缓存 3.4.5. 查询语言中的替换 3.4.6. Hibernate的统计(statistics)机制 3.5. 日志 3.6. 实现NamingStrategy 3.7. XML配置文件 3.8. J2EE应用程序服务器的集成 3.8.1. 事务策略配置 3.8.2. JNDI绑定的SessionFactory 3.8.3. JTA和Session的自动绑定 3.8.4. JMX部署 4. 持久化类(Persistent Classes) 4.1. 一个简单的POJO例子 4.1.1. 为持久化字段声明访问器(accessors)和是否可变的标志(mutators) 4.1.2. 实现一个默认的(即无参数的)构造方法(constructor) 4.1.3. 提供一个标识属性(identifier property)(可选) 4.1.4. 使用非final的类 (可选) 4.2. 实现继承(Inheritance) 4.3. 实现equals()和hashCode() 4.4. 动态模型(Dynamic models) 5. 对象/关系数据库映射基础(Basic O/R Mapping) 5.1. 映射定义(Mapping declaration) 5.1.1. Doctype 5.1.2. hibernate-mapping 5.1.3. class 5.1.4. id 5.1.4.1. Generator 5.1.4.2. 高/低位算法(Hi/Lo Algorithm) 5.1.4.3. UUID算法(UUID Algorithm ) 5.1.4.4. 标识字段和序列(Identity columns and Sequences) 5.1.4.5. 程序分配的标识符(Assigned Identifiers) 5.1.4.6. 触发器实现的主键生成器(Primary keys assigned by triggers) 5.1.5. composite-id 5.1.6. 鉴别器(discriminator) 5.1.7. 版本(version)(可选) 5.1.8. timestamp (optional) 5.1.9. property 5.1.10. 多对一(many-to-one) 5.1.11. 一对一 5.1.12. 组件(component), 动态组件(dynamic-component) 5.1.13. properties 5.1.14. 子类(subclass) 5.1.15. 连接的子类(joined-subclass) 5.1.16. 联合子类(union-subclass) 5.1.17. 连接(join) 5.1.18. 键(key) 5.1.19. 字段和规则元素(column and formula elements) 5.1.20. 引用(import) 5.1.21. any 5.2. Hibernate 的类型 5.2.1. 实体(Entities)和值(values) 5.2.2. 基本值类型 5.2.3. 自定义值类型 5.3. SQL中引号包围的标识符 5.4. 其他元数据(Metadata) 5.4.1. 使用 XDoclet 标记 5.4.2. 使用 JDK 5.0 的注解(Annotation) 6. 集合类(Collections)映射 6.1. 持久化集合类(Persistent collections) 6.2. 集合映射( Collection mappings ) 6.2.1. 集合外键(Collection foreign keys) 6.2.2. 集合元素(Collection elements) 6.2.3. 索引集合类(Indexed collections) 6.2.4. 值集合于多对多关联(Collections of values and many-to-many associations) 6.2.5. 一对多关联(One-to-many Associations) 6.3. 高级集合映射(Advanced collection mappings) 6.3.1. 有序集合(Sorted collections) 6.3.2. 双向关联(Bidirectional associations) 6.3.3. 三重关联(Ternary associations) 6.3.4. 使用 6.4. 集合例子(Collection example) 7. 关联关系映射 7.1. 介绍 7.2. 单向关联(Unidirectional associations) 7.2.1. 多对一(many to one) 7.2.2. 一对一(one to one) 7.2.3. 一对多(one to many) 7.3. 使用连接表的单向关联(Unidirectional associations with join tables) 7.3.1. 一对多(one to many) 7.3.2. 多对一(many to one) 7.3.3. 一对一(one to one) 7.3.4. 多对多(many to many) 7.4. 双向关联(Bidirectional associations) 7.4.1. 一对多(one to many) / 多对一(many to one) 7.4.2. 一对一(one to one) 7.5. 使用连接表的双向关联(Bidirectional associations with join tables) 7.5.1. 一对多(one to many) /多对一( many to one) 7.5.2. 一对一(one to one) 7.5.3. 多对多(many to many) 8. 组件(Component)映射 8.1. 依赖对象(Dependent objects) 8.2. 在集合中出现的依赖对象 8.3. 组件作为Map的索引(Components as Map indices ) 8.4. 组件作为联合标识符(Components as composite identifiers) 8.5. 动态组件 (Dynamic components) 9. 继承映射(Inheritance Mappings) 9.1. 三种策略 9.1.1. 每个类分层结构一张表(Table per class hierarchy) 9.1.2. 每个子类一张表(Table per subclass) 9.1.3. 每个子类一张表(Table per subclass),使用辨别标志(Discriminator) 9.1.4. 混合使用“每个类分层结构一张表”和“每个子类一张表” 9.1.5. 每个具体类一张表(Table per concrete class) 9.1.6. Table per concrete class, using implicit polymorphism 9.1.7. 隐式多态和其他继承映射混合使用 9.2. 限制 10. 与对象共事 10.1. Hibernate对象状态(object states) 10.2. 使对象持久化 10.3. 装载对象 10.4. 查询 10.4.1. 执行查询 10.4.1.1. 迭代式获取结果(Iterating results) 10.4.1.2. 返回元组(tuples)的查询 10.4.1.3. 标量(Scalar)结果 10.4.1.4. 绑定参数 10.4.1.5. 分页 10.4.1.6. 可滚动遍历(Scrollable iteration) 10.4.1.7. 外置命名查询(Externalizing named queries) 10.4.2. 过滤集合 10.4.3. 条件查询(Criteria queries) 10.4.4. 使用原生SQL的查询 10.5. 修改持久对象 10.6. 修改脱管(Detached)对象 10.7. 自动状态检测 10.8. 删除持久对象 10.9. 在两个不同数据库间复制对象 10.10. Session刷出(flush) 10.11. 传播性持久化(transitive persistence) 10.12. 使用元数据 11. 事务和并发 11.1. Session和事务范围(transaction scopes) 11.1.1. 操作单元(Unit of work) 11.1.2. 应用程序事务(Application transactions) 11.1.3. 关注对象标识(Considering object identity) 11.1.4. 常见问题 11.2. 数据库事务声明 11.2.1. 非托管环境 11.2.2. 使用JTA 11.2.3. 异常处理 11.3. 乐观并发控制(Optimistic concurrency control) 11.3.1. 应用程序级别的版本检查(Application version checking) 11.3.2. 长生命周期session和自动版本化 11.3.3. 脱管对象(deatched object)和自动版本化 11.3.4. 定制自动版本化行为 11.4. 悲观锁定(Pessimistic Locking) 12. 拦截器与事件(Interceptors and events) 12.1. 拦截器(Interceptors) 12.2. 事件系统(Event system) 12.3. Hibernate的声明式安全机制 13. 批量处理(Batch processing) 13.1. 批量插入(Batch inserts) 13.2. 批量更新(Batch updates) 13.3. 大批量更新/删除(Bulk update/delete) 14. HQL: Hibernate查询语言 14.1. 大小写敏感性问题 14.2. from子句 14.3. 关联(Association)与连接(Join) 14.4. select子句 14.5. 聚集函数 14.6. 多态查询 14.7. where子句 14.8. 表达式 14.9. order by子句 14.10. group by子句 14.11. 子查询 14.12. HQL示例 14.13. 批量的UPDATE & DELETE语句 14.14. 小技巧 & 小窍门 15. 条件查询(Criteria Queries) 15.1. 创建一个Criteria 实例 15.2. 限制结果集内容 15.3. 结果集排序 15.4. 关联 15.5. 动态关联抓取 15.6. 查询示例 15.7. 投影(Projections)、聚合(aggregation)和分组(grouping) 15.8. 离线(detached)查询和子查询 16. Native SQL查询 16.1. 创建一个基于SQL的Query 16.2. 别名和属性引用 16.3. 命名SQL查询 16.3.1. 使用return-property来明确地指定字段/别名 16.3.2. 使用存储过程来查询 16.3.2.1. 使用存储过程的规则和限制 16.4. 定制SQL用来create,update和delete 16.5. 定制装载SQL 17. 过滤数据 17.1. Hibernate 过滤器(filters) 18. XML映射 18.1. 用XML数据进行工作 18.1.1. 指定同时映射XML和类 18.1.2. 只定义XML映射 18.2. XML映射元数据 18.3. 操作XML数据 19. 提升性能 19.1. 抓取策略(Fetching strategies) 19.1.1. 调整抓取策略(Tuning fetch strategies) 19.1.2. 单端关联代理(Single-ended association proxies) 19.1.3. 实例化集合和代理(Initializing collections and proxies) 19.1.4. 使用批量抓取(Using batch fetching) 19.1.5. 使用子查询抓取(Using subselect fetching) 19.1.6. 使用延迟属性抓取(Using lazy property fetching) 19.2. 二级缓存(The Second Level Cache) 19.2.1. 缓存映射(Cache mappings) 19.2.2. 策略:只读缓存(Strategy: read only) 19.2.3. 策略:读/写缓存(Strategy: read/write) 19.2.4. 策略:非严格读/写缓存(Strategy: nonstrict read/write) 19.2.5. 策略:事务缓存(transactional) 19.3. 管理缓存(Managing the caches) 19.4. 查询缓存(The Query Cache) 19.5. 理解集合性能(Understanding Collection performance) 19.5.1. 分类(Taxonomy) 19.5.2. Lists, maps 和sets用于更新效率最高 19.5.3. Bag和list是反向集合类中效率最高的 19.5.4. 一次性删除(One shot delete) 19.6. 监测性能(Monitoring performance) 19.6.1. 监测SessionFactory 19.6.2. 数据记录(Metrics) 20. 工具箱指南 20.1. Schema自动生成(Automatic schema generation) 20.1.1. 对schema定制化(Customizing the schema) 20.1.2. 运行该工具 20.1.3. 属性(Properties) 20.1.4. 使用Ant(Using Ant) 20.1.5. 对schema的增量更新(Incremental schema updates) 20.1.6. 用Ant来增量更新schema(Using Ant for incremental schema updates) 21. 示例:父子关系(Parent Child Relationships) 21.1. 关于collections 21.2. 双向的一对多关系(Bidirectional one-to-many) 21.3. 级联生命周期(Cascading lifecycle) 21.4. 级联与未保存值(Cascades and unsaved-value) 21.5. 结论 22. 示例:Weblog 应用程序 22.1. 持久化类 22.2. Hibernate 映射 22.3. Hibernate 代码 23. 示例:复杂映射实例 23.1. Employer(雇主)/Employee(雇员) 23.2. Author(作家)/Work(作品) 23.3. Customer(客户)/Order(订单)/Product(产品) 23.4. 杂例 23.4.1. "Typed" one-to-one association 23.4.2. Composite key example 23.4.3. Content based discrimination 23.4.4. Associations on alternate keys 24. 最佳实践(Best Practices)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值