正文

HibernateNote(3)2008-04-27 11:18:00

【评论】 【打印】 【字体: 】 本文链接:http://blog.pfan.cn/ghlat520/34597.html

分享到:

第三章:对像关系映射基础
  本章内容:
     1)pojo持久化类的属性及访问原理
     2)Hibernate访问持久类属性的策略
     3)在持久化类的访问中加入程序逻辑 
                   4)代理主键与自然主键
                   5)Hibernate主键生成器
  
                       

 

   pojo持久化类的属性及访问原理
      1)pojo类使用JavaBean的风格,为需要访问的属性提供getXxx()和setXxx()方法。这两个
  方法也称为持久化类的访问。
      2)Hibernate在进行数据持久化时也会调用pojo类对应的getXxx()和setXxx()方法
  Hibernate会调用pojo类的getXxx()方法从pojo对像中获取数据,并把它保存到
  数据库中去,会调用pojo类的setXxx()方法把从数据库读出的信息写入到pojo对像去
      3)具体说当Hibernate的Session在执行save(),update(),delete()方法把数据写入数据库时
        会调用pojo类的getXxx()方法;当Hibernate的Session在执行get(),load()或find()方法从
               数据库中读取数据时,会调用pojo类的se.tXxx()方法 
            4)值得注意的是,Java应用程序不能访问持久化类的private的类型的getXxx()和setXxx()方法
              而Hibernate没有这个限制,它能够访问各种级别的getXxx()和setXxx()方法。


   Hibernate访问持久类属性的策略
 1)在mapping文件(对像-关系映射文件)中,<propery>元素的access属性用于指定Hibernate
    访问持久化类的属性方式。如果把这个属性设置为propery,这也是默认值表明Hibernate
    通过相应的getXxx()与setXxx()方法来访问类的属性.
    比如:<property name="cname" type="string" access="property">或
  <property name="cname" type="string">这样Hibnate就会在访问数据库时自动去调用           getName()方法与setcname()方法。不管这个pojo类中是否有cname这个属性。
                只要有get与set方法就行了也就是说可以像这样配置
                 Cust====pojo类============
                 public class Cust
                  {
    private String cname;//这个代码可以省略
   public void setCname(String cname)
                          {
    ...
                          }

   public int getCname()
                          {
    ...
                          }
    }


          在持久化类的访问中加入程序逻辑
 1)持久化类中的属性是与表中的字段保持一致。有时可能希望持久化类对表中的字段进一步进行分解
   我们就可以把这种分解的程序逻辑写在持久化类中。
        2)在Order表中有一个字段是订单日期。表现形式如:"2005年3月4日",现在希望对这个字段
   进一步分解,分成年、月、日。步骤如下:
     A:在Order类中加入年、月、日属性,只需要get不需要set。尽管这些属性在表中没有
       public class Orders implements java.io.Serializable  
     {
                 private int y;
     private int m;
     private int d;
             public void setDtm(String dtm)
         {
       this.y=Integer.parseInt(dtm.substring(0, 4));
       this.m=Integer.parseInt(dtm.substring(5,dtm.indexOf('月')));
       this.d=Integer.parseInt(dtm.substring(dtm.indexOf('月')+1,dtm.length()-1));
       this.dtm = dtm;
           }
            B:在Orders.hbm.xml文件中,无需映射Orders类的y,m,d属性,只需要映射dtm属性,它
              和Orders表的dtm字段对应
  <property name="dtm" column="dtm"/>
            C:尽管在Order表中没有定义d,t,m属性,由于Hibernate不会直接访问d,t,m属性而是调用
              getDtm()和setDtm()方法
      
        
    代理主键与自然主键
 1)关系型数据库按主键区分不同的记录
 2)每条记录的主键值是永远不会改变的,任何企图改变主键的操作都是极其错误的
 3)在订单表中如果把订单Id做为主键也是可行的。比如:订单Id由最大的记录号加上当前的日期来构    成但是以后如果需求发生了变化,则就必须修改数据库从而增加了数据维护的难度。        
        4)更合理的方式是使用代理主键,即不具备业务含义的字段,该字段一般取名为"ID",代理主键
          通常为整数类型,因为整数类型比字符类型要节省更多的数据库空间
        5)生成代理主键的方式:
              A:sql server数据库可以使用Identity标识例来进行
              B:oracle数据库可以通过Sequence中获取自动增长的标识符.
                1:create sequence My_sequence  start with 1 increment by 1
                2:创建一个Sequence标识列,以后可以通过curval与nextval属性获取值
                3:curval:返回序列的当前值。
                4:nextval:先增加序列的值,然后返回序列值
                5:执行select My_sequence.nextval from dual 把序列加载到进程中
                6:执行insert into 表名(My_sequence.nextval...)方式来从序列中获取值
     
         
   Hibernate主键生成器
                 1)关系型数据库是按照代理主键来区分一个表中的多条记录
                 2)而Java应用程序是通过内存地址来区分同一个类的不同对像
                    Person p1=new Person();
                    Person p2=new Person();
                    Person p3=p1;
                    System.out.print(p1==p2);//相等
                    System.out.print(p1==p3);//不相等
                 3)Hibernate使用OID(object identity)对像标识符来统一两者之间的矛盾的.
                 4)在运行时Hibernate根据OID来维持Java对像和数据库表中记录的对应关系
                 5)为了保证OID的唯一性与不变性,通常不是由调用者为OID赋值,而是由Hibernate来给
                    OID赋值。因此可以把OID的setId()方法设置为private类型,可以禁止Java应用程序
                    随便的修改OID.而把getId()方法设置为public类型,这使得Java程序可以读取持久化
                    类的OID
                    private int id;
                    private void setId(int id)
                    {
                      this.id=id;
                    }
                    public int getId()
                     {
    return id;
                     }
                  6)在mapping文件中<id>元素用来设置对象标识符,例如:
                    <id name="id" type="long" column="ID">
                <generator class="assigned"/>
                    </id>其中的<generator>子元素用来设定OID的生成器
                 7)通常Hibernate的主键生成器可以取以下几种:
                     1)increment生成器。该生成器是Hibernate自己的生成器,不依赖于具体的数据库
                       任何数据库都可以使用
                        A:在Xxx.hbm.xml配置文件中设置主键生成器:
                                    <id name="deptno" type="long">
                    <column name="DEPTNO" precision="2" scale="0" />
                                       <generator class="increment"/>
                                    </id>
                        B:执行save方法。会发生Hibernate会自动到初始阶段读取本表中最大主键值
                          select max(Id) from 表名
                          接下来向表中插入记录时,能在max(ID)的基础上递增,增量为1
                        C:下面考虑两上Hibernate应用进程访问同一个数据库的情景:
                           假定第一个进程中的Hibernate在初始化阶段读取表中的最大主键为6
                           接着第二个进程中的Hibernate在初始化阶段读取表中的最大主键为6
                           接下来两个进程中的Hibernate各自向表中插入主键值为7的记录会出现错误
                        D:结论increment不适合于多个进程同时访问数据库的情景
                   2)sequence生成器。该生成器是Hibernate调用Oralce数据库的sequence自动获取值之后               再进行填充的生成器.
                        A:在Xxx.hbm.xml配置文件中设置主键生成器:
                                   <id name="deptno" type="long">
                <column name="DEPTNO" precision="2" scale="0" />
                <generator class="sequence">
                  <param name="sequence">chen_seq</param>
                                                 此处的name必须写成sequence形式
                </generator>
               </id>
                        B:在进行save方法时Hibernate先从底层数据库的chen_seq序列中获得一个唯一的
                           序列号,再把它做为主键值。
                    3)assigned主键由用户自己决定

阅读(2479) | 评论(0)


版权声明:编程爱好者网站为此博客服务提供商,如本文牵涉到版权问题,编程爱好者网站不承担相关责任,如有版权问题请直接与本文作者联系解决。谢谢!

评论

暂无评论
您需要登录后才能评论,请 登录 或者 注册