Hibernate逍遥游记——(二)对象—关系映射技术

本文详细介绍了Hibernate的对象关系映射技术,包括持久化类的属性访问、对象标识符(OID)设置、一对一、一对多、多对多等各种关联关系的映射方法,以及动态SQL语句的控制。通过示例解析了映射文件中的各个元素,如等,帮助开发者深入掌握Hibernate的ORM技巧。
摘要由CSDN通过智能技术生成

1.对象关系映射基础

1.1 持久化类的属性及访问方法

持久化类的访问方法有两个调用者:

  •  java应用程序:通过持久化类的getter和setter方法进行访问。
  •  Hibernate :通过持久化类的getter和setter方法或通过java的反射机制进行访问

注意:

java应用程序不能访问持久化类的private类型的getter、setter方法,而Hibernate可以。

持久化类中的属性类型可以是基本类型或包类型,他们对应相同的Hibernate映射类型。但基本类型无法表示null值,推荐使用包类型。

1.2 Hibernate访问持久化类属性的策略

通过设置映射文件中的<property>元素的access属性的方式。

  • access="property"(默认),指定Hibernate通过setXXX和getXXX方法访问持久化类属性(最佳实践)。
  • access="field",指定Hibernate通过java反射机制直接访问类的属性。

1.3 派生属性的映射

派生属性:持久化类的某些属性的值在运行时通过计算得出。

1)在持久化类中虽没有某个属性,表中有这个属性。

  解决:在持久化类中设置该属性对应的setter和getter方法,并加入处理逻辑,然后在映射文件中映射该属性,则Hibernate就可以访问。

2)持久化类中有某个属性如avgAge,但表中没有该属性。

  解决:通过<property>的formula来设置一个SQL表达式,Hibernate在运行时计算出派生属性的值。

1.4 控制Hibernate生成的insert和update语句

 HIbernate在初始化阶段,根据文件的映射信息,为所有的持久化类预定义SQL语句(insert、update、delete、select)并将其保存在SessionFactory的内置缓存中。

当session执行相应的方法时(save、update、delete、load、get),直接从缓存中调用预定义的SQL并绑定参数。

通过设置动态SQL语句提高性能, 即在持久化类的映射文件中将class的属性 dynamic-update设置成true,则Hibernate可以根据Session中保存的Monkey快照,在update时只会包含需要更新的字段。

注意:

HIbernate有两种配置文件:hibernate.properties和hibernate.cfg.xml。HIbernate默认会到classpath路径下加载hibernate.properties文件。 如果该文件不存在,则通过Configuration的configure()显示加载hibernate.cfg.xml。

2.映射对象标识符OID

2.1 对象标识符(OID)

  •  java语言使用内存地址来识别和区分同一个类的不同对象;
  •  关系数据库按主键值来识别和区分同一个表的不同记录;
  • Hibernate使用对象标识符(OID)来建立Session缓存中的对象和数据库表中记录的一一对应关系(session中对象的OID和数据库表的主键一一对应)。

2.2 主键设置自动增长

常用数据库主键设置自动增长:Mysql采用 auto_increment;MS SQL Server采用 identify ;Oracel使用序列(Sequence)中获取自动增长的标识符。

最佳实践:将持久化类的OID的setId()方法设置成private类型以防止Java应用程序随便修改OID。而将getId()设置成public使得Java应用程序可以读取持久化对象的OID。

2.3 Hibernate的内置标识符生成器

持久化类的映射文件中<generator>子元素的calss属性用来设定标识符生成器。

Hibernate的常用标识符生成器:increment、identity、sequence、hilo、native等。
  • increment:由Hibernate以递增的方式为代理主键赋值。在单个应用服务器上可以有效工作,不适合集群环境。
  • hilo:由HIbernate按照一种high/low算法来生成标识符。不依赖于底层的数据库系统。
  • identity:由底层的数据库来负责生成标识符。要求数据库把主键定义为自动增长字段类型。
  • sequence:由底层的数据库提供的序列来生成标识符。要求底层的数据库系统必须支持序列。
  • native:依据底层的数据库对自动生成标识符的支持能力,选择用identity、sequence或hilo标识符生成器。它能自动判断底层数据库提供的生成标识符机制。

最佳实践:使用native标识符生成器,可以跨数据库平台。

2.4 补充说明

关系数据库中的主键可以分为自然主键(具有业务含义)和代理主键(不具有业务含义),代理主键更加流行,且通常为整数类型。与此对应,在持久化类中应把OID定义为整数类型,Hibernate把OID定义为long、int或short。

3.映射一对多关联关系

说明:一对多关联与多对一关联在本节中意义等价。

在关系数据库中,只存在外键参照关系,而且总是由“many”的一方参照“one”的一方。实际上关系数据库中只存在多对一或一对一的单向关联。假设存在如下图3-1所示的关系:

图3-1 MONKEYS表参照TEAMS表


3.1 建立多对一的单向关联关系

持久化类Monkey与Team是多对一的关系,在Monkey中有一个Team类型的team属性。

public class Monkey {
          ...  

    private Team team;
        ...
  
}
Monkey通过Monkey.hbm.xml映射MONKEYS表,其中:
  • name映射NAME,类型相同String类型,使用<property>映射:
      <property name="name" type="string" column="NAME" />  <!--type="string"为Hibernate的映射类型-->
  •  team(Team类型)映射TEAM_ID(整型),类型不匹配,使用<many-to-one>映射     
  <many-to-one

            name="team"                       <!--持久化类Monkey中要映射的属性team-->

            column="TEAM_ID"                  <!--同持久化类的属性对应的表的外键TEAM_ID-->

            class="mypack.Team"               <!--表明team属性的类型为mypack.Team->

            cascade="save-update"             <!--默认为none,设置级联保存和更新-->

            lazy="false"                      <!--立即加载策略,默认为true-->

       />
说明:cascade的值设置成save-update,可以保证当Hibernate在持久化临时对象时会自动持久化其所关联的其他临时对象。也就是说,在保存或更新Monkey对象时,会自动保存或更新与之关联的Team对象。 

3.2 映射一对多双向关联

前面3.1中已经建立了Monkey端的多对一单向关联,再加上本节Team端的一对多关联,就是双向关联了。
  • 在Team中增加如下属性:  
   public class Team{
                  ...
                private Set monkeys = new HashSet();
                   ...
       }

最佳实践:在持久化类中声明接口类型的集合属性,并为他初始化为集合实现类的一个实例(可扩展、健壮性)。

  • Team通过Team.hbm.xm与TEAMS映射,· 映射monkeys属性(TEAMS表中没有与其对应的字段),使用<set>
   <set 
                name="monkeys"                           <!--持久化类Team中要映射的属性monkeys-->
                inverse="true"                           <!--控制权交给Monkey-->
                cascade="save-update"                    <!--默认为none,设置级联保存和更新-->
                >
        
            <key column="TEAM_ID" />                     <!--表明关联Monkey对应的表MONKEYS的外键-->       
            <one-to-many class="mypack.Monkey" />        <!--表明monkeys集合中的对象为Monkey类型-->
     </set>  
最佳实践:在建立一对多的双向关联关系时,应该在“ one ”的一方把 <set> 元素的 inverse 属性设置为 true,可以提高应用的性能。在建立两个对象的双向关联时,同时修改关联两端的对象的相应属性。
  •    再议cascade

     delete—— 级联删除,删除一个持久化对象(如Team)时,会自动删除与之关联的持久化对象(Monkey

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值