关于Hibernate学习笔记

关于Hibernate框架


    一. 主键生成方式


       1. 在映射关系文件中,需要配置主键字段,并配置其主键的生成 


          方式, 即通过generator标记来配置主键生成的方式。


       2. 主键生成的方式有如下:


          (1) sequence(*)
              
              ---语法


                 <generator class="sequence">
                     
                     <param name="sequence">


                          序列名   


                     </param>
            
                 </generator>       


              ---解释


                 sequence是采用序列方式生成主键,适用于Oracle数据库。


          (2) identity(*)


              ---语法


                 <generator class="identity">




                 </generator>


              ---解释


                 identity是使用数据库自增长的机制来生成主键,适用于


                 除了Oracle以外的数据库。


          (3) native(*)


              ---语法


                 <generator class="native">
                    
                      <param name="sequence">
                        
                           序列名


                      </param>
                       


                 </generator>


              ---解释


                 native是让Hibernate自动选择一个主键生成方式,它


                 会根据主配置文件中指定的方言,从sequence和identity中


                 选择一个。即如果配置的方言是Oracle则选择sequence,否则


                 就选择identity。




           (4)increment


              ---语法
 
                 <generator class="increment">




                 </generator>          


              ---解释


                 increment是采用Hibernate组件生成的ID,并不是使用


                 数据库的机制。该组件会自动取出当前表的ID最大值,然后+1
 
                 作为新的ID。


                 优点:适用于所有数据库。


                 缺点:当并发量大时,会出现重复主键的情况。


                 不推荐使用。


           (5)assigned


              ---语法


                 <generator class="assigned">




                 </generator>   


              ---解释


                 assigned,Hibernate不会自动生成主键,主键的生成完全交给


                 程序员来处理。


           (6)hilo/uuid


              ---语法


              <generator class="hilo或uuid">




              </generator>   


              ---解释


              采用hilo/uuid的算法来生成一个主键,该主键


              是一个很长的字符串,并且没有规律,但是可以保证


              不重复。




     二.  一级缓存


          1.什么是一级缓存
  
            Hibernate在创建session时,会给每一个session分配一块


            内存空间,用于缓存查询到的对象数据,这块内存空间称之为


            一级缓存。由于该空间是给session使用的,也称session级缓存。


            重点:


             (1)一级缓存又称为session级缓存


             (2)一级缓存是session独享的 


           2.为什么用一级缓存


             (1) 作用 


                  一级缓存可以降低数据库访问次数,提高代码执行效率。


             (2) 步骤


                 ---session取值时会优先向它的一级缓存取值


                 ---如果缓存中没有数据,它会向数据库取值,并将


                    取到的值放入一级缓存,然后session从缓存中取出数据。


                 ---当再次查询相同的数据时,由于一级缓存中已经存在了该


                    数据,则直接返回,不需要重新访问数据库。




           3.如何使用一级缓存


              (1)一级缓存是默认开启的,自动使用
  
              (2)规则:


                  ---一级缓存是session独享的,即一个session不能


                     访问另一个session缓存的数据


                  ---每次查询,session仅仅是把本次查询结果放到一级


                     缓存中
              
                  ---如果查询到的结果是多条数据,session这些数据拆开,


                     以单个对象的形式存入一级缓存。


                  ---在执行save,update,delete时,会自动触发缓存的
 
                     更新(与对象持久性有关)。


               (3)一级缓存是给session使用的,并且是由session负责管理,
      
                  session管理一级缓存的方式如下:


                  a. session.evict(obj)


                     evict可以将obj对象从当前session的缓存区移除.


                  b. session.clear()


                     clear可以将当前session的缓存区清空


                  c. session.close()


                     session关闭时,它会释放自己的缓存区域,从而


                     缓存数据也释放了。


     三. 对象持久性


        1. Hibernate下,可以把对象看做具有3种状态,分别为临时态,持久


           态,游离态,对象持久性是指对象在这三种状态之间的转换规则。


        2. 三种状态的转换及规则


           (1)临时态


              a. 转换


               --new出来的对象是临时态的


               --delete持久态的对象,它将转变为临时态


              b. 规则


               --临时态的对象可以被垃圾回收


               --临时态的对象没有被持久化过,并且没有与session建立关联。




            (2)持久态


               a.转换


               --通过save/update操作过的对象是持久态的。


               --经过get/load/list/iterate方法查询到的对象是持久态的。


               b.规则


               --持久态的对象不能被垃圾回收


               --持久态的对象被持久化了,并且与session建立起了关联。   


               --(*)持久态的对象存在于一级缓存中


               --(*)持久态的对象可以自动与数据库同步,同步的时机


                    是调用session.flush()时,实际上事务提交时也可以


                    同步,原因是 ts.commit()=session.flush()+commit;


                    


            (3)游离态


               a. 转换


                --通过evict/clear/close操作过的对象,是游离态的


               b. 规则


                --游离态的对象可以被垃圾回收


                --游离态的对象被持久化过,但是已经与session解除了关联。










      
    
   一. 关联映射 


       1.什么是关联映射


         如果两张表有关联关系,Hibernate允许我们将此关系提取


         出来,并配置在映射关系文件中。在对其中一张表进行增、删、


         改、查时,Hibernate可以通过这个关系的描述,自动生成对另


         一张表的增、删、改、查的SQL,并自动执行。这种对两张表的


         关系的配置及使用,称之为关联映射。


       2.关联映射的作用


         当我们操作一张表时,可以通过关联映射自动生成操作另一张表的


         SQL,并自动执行。


       3.使用步骤


         (1)明确两张表的关系,以及关联字段。
 
         (2)在实体类中追加关联属性,来封装关联查询的结果。 
         
         (3)在映射关系文件中,追加2张表的关联关系配置。


       4.关联映射的类型


         (1)一对多


         (2)多对一


         (3)多对多


    二. 一对多关联  


        1.作用
      
          可以在我们访问"一"的一方数据时,自动访问"多"的一方


          的数据,比如:在查询账务账号时,自动查询出它对应的全部


          业务账号。
          
        2.案例


          在查询账务账号时,连带查询出它对应的所有业务账号。


        3.开发步骤  


          (1)明确表的关系及关联字段


             account表与service表具有一对多的关系,其关联字段


             是service.account_id=account.account_id


          (2)在实体类中追加关联属性


             在Account中追加属性来封装业务账号数据,即增加集合类型


             属性,集合中封装的是Service,如 Set<Service> services;


          (3)在映射关系文件中配置关联关系    


             需要动态拼写如下SQL:


                select * from service where account_id=?


             需要哪些条件:


                 a、表名


                 b、关联字段


                 c、2张表的关系


                 d、查询结果存在哪个属性上


                 有一个默认前提:
          
                     一的一方表的主键,作为多的一方表的外键。即account
                    
                     表的主键,作为service表的外键。
                     


             语法:


                 <!--指定条件d-->


                 <set name="services">


                     <!--指定条件b-->
 
                     <key column="account_id"/>  


                     <!--指定条件a、c-->


                     <one-to-many class="entity.Service"/>


                 </set>
                 
    三.多对一关联


       1.作用


         设置好多对一关联之后,可以在操作"多"的一方数据时,自动操作


         另一方的数据,比如在操作service时自动操作account


       2.案例


         希望在查询业务账号时,自动查询出该业务账号对应的账务账号。


       3.开发步骤


         (1)明确关联关系及关系字段。


            service与account具有多对一的关系,关系字段是service.account_id=account.id


         (2)在实体类中追加关联属性


            在Service中追加属性Account account;


         (3)在映射关系文件中增加配置


            需要拼如下的SQL


            select * from account where account_id in(


                select account_id from service where service_id=?


             );


            需要提供如下条件:


               a 对方表名


               b 关系字段


               c 表之间的关系


               d 查询结果封装到哪个属性


           语法:


              <!--
                  many-to-one:c
                  name,class:d
                  column:b
                  class:a


                 --> 


              <many-to-one 


                  name="account"
        
                  column="account_id"


                  class="entity.Account"


               />


           
          (4) 注意


              多对一关联时,Service类中的accountId 可以省略,并且


              Service.hbm.xml中的accountId 的配置也可以省略。 


              原因是这个外键属性主要是用于查询Account数据的,但是现在


              多对一关联已经把Account查询出来了,因此该查询就可以省略。




    四. 关联操作


        1.关联查询   
    
          (1)延迟加载


             对于关联属性,Hibernate默认采用延迟加载的机制。  


             lazy="true": 采用延迟加载(默认)


             lazy="false":不采用延迟加载


          (2)采用连接查询


             fetch="select":不采用连接查询(默认)
                 
             fetch="join"  :采用连接查询,此时lazy属性失效。 


          (3)采用join fetch拼hql


             --account关联service


                from Account a join fetch a.services where a.id=?
                
                (提示:由于是hql语句,所以where后面a.id中的id是属性名,不能使account_id字段名)


             --service关联account


                from Service s join fetch s.account where s.id=?
                
                (提示:意义同上)


       2.级联操作


         (1) 什么叫级联操作


              在Hibernate里,在对一方进行增、删、改时要自动的对另一方


              也进行增、删、改,这样的行为称之为级联操作。


         (2) 如何实现级联的添加,修改,删除    


              在要操作的对象的映射关系文件中,在关联属性上追加cascade属性,


              用这个属性的值来指定级联方式:


              cascade="none"  
  
                不支持级联(默认)         


              cascade="save-update"


                支持级联添加、修改


              cascade="delete" 
 
                支持级联删除


              cascade="all"


                支持级联添加、修改、删除
 
         (3)案例


            在添加、修改、删除账务账号时,同时添加、修改、删除业务账号。


            注:通常情况下,都是通过"一"的一方来级联"多"的一方,很少


            有通过"多"级联"一"的情况。




         (4)inverse


            在一对多进行级联添加、删除时,Hibernate在操作主表account时,
            
            它认为外键字段有必要由account方来进行维护,因此它会


            以acccount方触发一个单独更新外键字段的行为,即


            update service set account_id=?/null where service_id=?


            而实际上,级联添加、删除service时,添加、删除本身就已经可以


            维护外键字段(由于外键在service表中),因此一对多时主表触发


            的外键维护时多余的,可以去掉,所以把inverse="false"这种默认


            值该为inverse="true"就可以达到让主表放弃维护外键的目的了。 


            注: inverse="true"中inverse是反转的意思,整句是指主表方反转对


            外键字段的维护权,即交出这个维护权,所以此时主表不再生成


            update语句维护外键字段。




         (5)注意:


            级联删除时,需要在配置文件的关联属性上追加inverse="true"


          
    五.多对多关系映射


       1.作用  


         在操作一方对象时,Hibernate可以自动根据关系映射操作另一方,


         操作包含增、删、改、查。


       2.案例


         在查询管理员时,可以自动查询对应的角色,在新增、修改、删除


         管理员时,可以自动新增、修改、删除管理员角色中间表。 


       3.开发步骤


         (1)明确关联关系及关系字段 


            admin_info与role_info具有多对多的关系,关系字段是:


            admin_role.admin_id=adminer_info.id


            admin_role.role_id=role_info.id
 
         (2)实体类中追加关联属性


            在管理员实体类Admin中追加属性封装角色,即Set<Role> roles;


         (3)在映射关系文件中配置关系


            需要自动拼如下sql:(可查询出某个管理员对应的角色)


            select * from role_info where role_id in(


              select role_id from admin_role where admin_id=?


            );


          需要提供如下条件:


            a. 对方表名role_info


            b. 中间表名admin_role


            c. 对方表的关联字段role_id


            d. 当前表的关联字段admin_id


            e. 2张表的关系
 
            d. 查询结果封装到哪个属性




         配置语法:


               <!--b,f-->   
            
            <set name="roles" table="admin_role">


               <!--d-->


              <key column="admin_id"/>


               <!--a,c,e-->
  
              <many-to-many 
           
                class="entity.Role" 


                column="role_id" />


            </set>




      4.关联操作


        (1)关联查询  
    
           a. lazy属性的使用同一对多


           b. fetch属性的使用同一对多


           c. join fetch(即拼写hql来进行多对多的关联)


        (2)关联增加、修改、删除
 
           在增加、修改、删除当前表时,自动增加、修改、删除中间表的数据


        (3)级联增加、修改、删除   


           在增加、修改、删除当前表时,自动增加、修改、删除对方表以及


           中间表的数据。


                cascade="save-update"


                   增加,修改


                cascade="delete"


                   删除


                cascade="all"


                   增加,修改,删除
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值