hao861002 发表于 2013-1-13 18:56:21

hibernate复习第二天

一、id 生成方式
    1,序列sequence 只适用于Oracle,     seqhilo 就不用自己建sequence;默认用数据库里的hibernate_sequence;
        <id name="id" column="id">
                <generator class="seqhilo"> <!--  hibernate_sequence.nextval  -->
               
         <generator class="sequence">
          <param name="sequence">person_seq</param><!--指定sequence名-->
         </generator>
        </id>
    2,自增列,适用于SQLServer和mysql
          mysql建表时加上:id  integer auto_increment primary key,
          SQLServer加上:identity
         
        <id name="id" column="id">
         <generator class="identity"/>
        </id>
   
    3,从表中取最大值加一,DB2和mysql
        <id name="id" column="id" type="integer">
         <generator class="increment"/>
        </id>
       不适合多线程;不多用;
   
    4,根据底层数据库指定生成方法;
   
     <id name="id" column="id">
      <generator class="native"/>
     </id>
     hibernate自己选用哪种生成方式;
            对于Oracle来说还是用的hibernate_sequence ;
            这种比较方便;
           
    5,高低位算法;跟数据库无关的;
   
        <id name="id" column="id">
          <generator class="hilo">
           <param name="table">high_value</param>
           <!--设置高位值取值的表-->
           <param name="column">next_value</param>
           <!--设置高位值取值的字段-->
           <param name="max_lo">50</param>
           <!--指定低位最大值,当取道最大值是会再取一个高位值再运算-->
          </generator>
        </id>
   
     6, uuid 全球唯一的数字,根据时间,ip地址等计算,保证不同;32位16进制;
                  但是是字符串格式的;将id也改成字符串格式即可;将表的字段长度加长,最少32位;
           <generator class="uuid.hex"/>
      
          assigned:自赋值
          select ,foreign ;从别的表取;
 二、基本类型
       Date :java里的类型
       存日期类型时,要指明 type="date" ,  告诉hibernate 用数据库中的哪种类型;
       大多数情况下可以省略type;
 
 三、关联映射:
        关联关系的数量和方向,从面向对象的角度去理解,不要面向数据库去理解;
    1、 一对一:
        java中的一对一,就是互相维护一个引用
     
      1)  唯一外键: 
      
   a. (单向一对一)
        数据库中主外键的关系其实是一对多的关系:
      
        A  pk - fk(b-pk)        n       外键可以多次引用一个主键;
        B  pk                          1 
        要想变成唯一,在外键的表上加上unique约束;
       
        Address 实体类里,有几个属性才在xml文件里配置;
        在Account 里有一个Address的引用,叫关联属性;
        代表了单向的一对一的关系;
       
        <many-to-one  name="addr" column="fid"  unique="true"  cascade="all">
        name是属性的名字;column是字段名;是一个唯一外键,引用另一张表的主键;
                表示一个account对应一个address;不能多个account对应一个address
                数据库里用的是外键,必须用<many-to-one> 标签;
             
                many  ->   account
                one     ->   address     只知道address是一;不知道account是几;需要去address里去读;
                unique=true;//表示我这里是一;不加就表示单向的多对一了;
                到address里去读就是0;因为没有我的引用;
               
                从逻辑上不知道是多对一还是一对一;所以写 标签上写 <many-to-one> ;
                写不写unique=true ; 这就需要从业务来考虑;
                
                 站在PO的角度考虑写什么标签;至于业务上的要求,再加约束;                          
        cascade :级联操作,存本对象时关联存子对象;重点考虑;
                      只存account,便会关联去存address;
        unique=true :表示外键唯一;
       
        create table ln_address(
   oid number(20) primary key,
   postcode varchar2(20),
   city  varchar2(20),
   street  varchar2(30)
        );
        create table ln_account(
         aid number(20) primary key,
         actNo varchar(100) not null,
         owner  varchar(20) not null,
         balance number(20,2),
         fid number(20) not null unique,
         constraint account_address foreign key(fid)
                references  ln_address(oid)
        );
       
                     ?:1    m:1 
        Account : address    ?-----> 1  Address
        <many-to-one>     //在不明确的情况下写这个
        <one-to-one>    //在很明确的情况下写这个,即使很明确的情况下也可以用<many-to-one>
      
    b.  (双向一对一)
         在Address  中加一个  account 属性;
        
         在 Address 中的 setAccount(Account  a){  this.account=a;
                                                                        addr.setAccount(this);
                                                                  }
         不能两边都加;否则死循环;在哪边加都可以,看业务需求;
         
         在Address的配置文件中加上:
         <one-to-one  name="account"  cascade="all">
        
          只能在一边写 <many-to-one> ;并且给外键加上唯一约束;
 
          <many-to-one> 和 <one-to-one> 可以互换;
          那么将外键移到address表里,它的xml文件就是<many-to-one>
          account的xml文件就是<one-to-one> ;
          外键在哪个表里,哪个标签就是<many-to-one>;
         
          这时候存方向的哪一方都会级联存另一方;
          注意:表没有单向和双向的关系;
         
          存 address 时 ,正常存属性 ,读到 <one-to-one> 时,一对一是po之间的关系;
                    知道了是关联属性,到另外一个映射文件中,
                    name=“account” ,找到account所对的类的映射文件;
                    存account 表,表里有一个外键,把address的主键拿过来存进来就行;
                   
                    先存主键的一方,外键才有值;
                    在hibernate.cfg.xml中加上,映射文件写好后;自动产生表:
                    <property name="hbm2ddl.auto">create</property> 
                    每次都是新建表,所以记录都是刚刚插入的记录;
                   
   2)共享主键:这个用的多;POJO类不用变;
    address 的主键又是外键 和 account 的值一致;
  
    account的xml文件:
    <one-to-one  name="address"  cascade="all" >
   
    address 的xml文件:
  
     <id name="oid" column="oid">    既是主键又是外键;值是从它引用的外键得到的;
  <generator class="foreign">   <!--表示主键引用的是别的表 -->
       <param name="property">account</param>
  </generator>
    </id>
   
    <one-to-one name="account"
                      constrained="true" cascade="all"/>
                     
    constrained="true";//acct所对应的类型的表,account表,对我现在的表形成了外键约束;
                                //account表的主键对address表的主键形成了外键约束;
                               
    上边和下边一一对应;是互补的;
 四 、HQL  Query
  1、
    from + 表名; //查询表中的所有对象的集合;
    Query q=s.createQuery("from Account");
    List l=q.list();
    Iterator it=l.iterator();
    while(it.hasNext()) {
     Account acc=(Account)it.next();
     System.out.println(" owner: "+acc.getOwner()+" balance: "+acc.getBalance());
    }
   
  2、  Account acco=(Account)q.uniqueResult();//只有确定只有一个对象时才能用这个;
  3、  条件查询:
       Query q=s.createQuery("from  Account a where a.actNo=?");
       q.setString(1,"10001");
       acco=(Account)q.uniqueResult();//规定帐号唯一;只能返回一条记录;
     
       "from Account a where a.actNo=:actNo"
 q.setString("actNo",xxx);
 或者
 "from Account a where a.actNo=?"
 q.setString(0,xxx);
页: [1]
查看完整版本: hibernate复习第二天