hibernate进阶

一.持久化对象概念

     1. 就是数据库表对应的pojo类

     2.  三种状态:

         ①瞬时态:(临时态,自由态) 一般指我们new 出来对象, 他不存在oid, 与我们hibernate session无关联,
                           不存在oid在数据库无记录,他使用完成后,会被JVM直接回收掉,只是用于信息携带;

         ②持久态 : 由hibernate session管理,具有持久化表示oid,他的特点,在事物未提交前,一直是持久态.
                      oid由session管理, 在数据库中数据有可能有,也可能没有,他发生改变时,hibernate能检测到.

         ③托管态:(也叫游离态,离线态), 持久太对象失去了session关联,存在oid,在数据库中有可能有,也可能没有
                        对于托管态对象,他发生改变时,hibernate不能检测到.

   3.判断持久态对象三种状态: new 对象的时候就是瞬时态,无oid  session.save(c) : 是持久态,生成策略生成id ,
                                             比如:当session关闭, 就变成了游离态,但是还有oid;

   4.三种状态的相互转换 :
         瞬时态 -- -> 持久  save  saveOrUpdate
         瞬时态----->托管: 手动设置oid;(不建议)
         持久态---> 瞬时  delete() 被删除或持久对象(不建议)
        持久态---> 托管 session他的缓存就是一级缓存;清除一级缓存 evict(清除查询出的对象) clear(清空缓存)
                                   close(关闭一级缓存)

        托管态-->瞬时:  是无法直接获取,直接将oid删除;(不建议)
        托管态-->持久态: update  saveorupdate

  5. hibernate 持久对象具有自动更新数据库的能力;查到一个对象, 改变对象的属性值, commit后,数据库会自动更改
     一级缓存他底层使用一个map来存储,  map的key 存储的是一级缓存对象, value存储的是快照(就是对象的属性)
      当对象的属性改变时,一级缓存对象改变了,当session关闭,事物提交, 会判断一级缓存和快照是否一样,
      如果不一样,他就会发送update语句;

 
二 hibernate缓存介绍:

      一级缓存介绍:

     1. hibernate的一级缓存指的是session缓存: 在session中定义一系列的集合来存储数据,他们构成了session缓存
                                                                          只要session没有关闭,他就会一值存在;

      2. 当我们通过hibernate中的session提供的API进行操作时,就会将持久化对象保存session中,当下一次在查询
                        缓存中具有对象(oid来判断), 就不会去数据库查询,直接从缓存中获取,

       3.  hibernate的一级缓存存在目的就是为了减少对数据库访问.


       4.actionQueue 他是一行列队列,它主要记录crud操作的相关信息;   
          persistencecontext: 他是持久化上下文, 他是真正的session缓存;


       5  一级缓存操作常用的API  :

           ①.当我们通过session的save,update,saveorupdate操作时,如果缓存中没有,就会从数据库中查询到,
                                                                                                                         然后存到一级缓存中
           ②.session.clear; 清空一级缓存 , session.evict(c 查询出来的对象); 从一级缓存中删除一个指定的对象;

           ③ session.refresh(c 查询出来的对象);重新查询数据库, 用数据库里面数据来同步一级缓存和快照;

           ④update: 针对托管对象,持久对象具有自动更新能力.直接操作托管对象,他会将托管对象转为持久对象再操作;
                  如果session中出现相同的oid,会产生异常; 如果托管对象的oid不存在执行update,会产生异常;

            ⑤saveorupdate : 如果对象是一个瞬时对象----执行save操作, 如果是托管对象---执行update,
                    如果是持久对象他会自动去数据库更新;

            ⑥ delete: 删除一个托管对象,与session关联,再删除, 先删除一级缓存,再删除数据库;.

 

     二级缓存:  他是sessionfactory级别缓存,人为指示缓存;

      6. 很少被修改的数据,不是很重要的数据,允许出现偶尔并发的问题, 存储在硬盘中.

      7.缓存插件: ehcache:  1. 导入jar包, 目录在 /源码/lib/ehcahe 三个jar包,
 
               project/etc/ehcahe.xml 放在src下;  eternal 缓存是否持久,

               timetoidleseconds: 系统当机,是否保存到磁盘, tolive: 闲置n秒后销毁;

                overflowtodisk: 内存中缓存达到最大上限,就缓存到硬盘.


    8.在核心配置文件中,  1.开启二级缓存, 开启查询缓存, 配置二级缓存的regionfactory  配置哪些类需要缓存


三.hibernate关联查询

     注意: 在两张表相互关联时,都写了tostring, 就会发生栈溢出

    1.数据对象的三种关系;

          一对一: 原则有两种, 唯一外键对应(在任意一方添加外键),  主键对应;
                         在设计实体类时候,分别在对方,添加对方的对象为成员属性;
           一对多: 在数据库:  在多的一方添加外键列,
                       在类中:在多的那个类中添加对象为成员属性; 在一的那个类中添加一个集合
          多对多: 添加第三张表,描述其对应关系.    在类中: 分别在对方类中的成员属性中,添加对象集合.


   2. hibernate 关联映射

     ①  一对多,在多的hbm.xml中,

              <many-to-one name="对象引用名称" class="全类名" column="外键名称">
             在一的一方xml中,  <set name="set集合名称"> <key column="外键自动名称"></key><one-to-man class="全类名">


            注意: 一和多的的两边的column外键名称要一致;同样的有list,map标签, 多对多要在集合标签下面<many-to-many>

     ②测试单向保存,只保存订单,就会在两个表内添加数据.需要在订单配置文件中,
           在<many-to-one cascade="save-update">,这样客户也会保存.保存客户时,保存订单,在 <set cascade="save-update">


     ③双向关联,  在配置要双向管理类. 可以通过任意一方来操作对方;

            1. 在操作代码尽量不要进行双向关联, 比如: 客户添加了订单,订单就不用在添加哪个客户了. 会造成资源浪费;

            2. 如果使用 双向关联,会存在多余的update语句,
               解决: 在set标签上 inverse="turn" 是否反转   如果为true,由对方来维护外键, 反之,为本方维护;
               外键在哪一个表中,就由谁维护;

   ④ 对象导航: 基于cascade, 两个表内都写了这个属性.根据关联的关系可以进行多条插入语句.
 
   ⑤删除订单,不需要删除客户,在set标签中 cascade="delete-orphan" 删除客户.需要删除订单. 在set标签中 cascade="delete"
 

 3.使用cascade可以完成级联操作 , 它可常用取值: none这是一个默认值
     save-update,当我们配置它时,底层使用save update或save-update完成操作,级联保存临时对象,如果是游离对象,

                             会执行update.
      delete 级联删除
      delete-orphan 删除与当前对象解除关系的对象。(删除孤儿)

      注意:他们之间的区别: 删除孤儿,是当他是持久态的时候,查询出list集合,执行remove集合数据,他会更新到数据库
      all 它包含了save-update  delete操作
      all-delete-orphan 它包信了delete-orphan与all操作


  4.cascade与inverse有什么区别?
        cascade它是完成级联操作,例如: 保存一方需要保存另一方
        Inverse它只有在双向关联情况下有作用,它来指定由哪一方维护外键; 解决资源浪费;
 

四: 注解开发

      1.  po类注解配置:
             @Entity   //定义实体   @table(name="表名", catalog="库名")
             @id 注解 @Generatedvalue(strategy=GenerationType.策略名)  不写参数是 默认的native
             @column(name="数据库列名" ,length=30,nullable=true(是否为空))  @Temporal(TemporalType.日期类型)
             如果成员属性没加注解,也会自动生成表中;列的名称就是属性名称
             在核心配置文件中 <mapping class="全类名">
                
           主键生成策略使用UUID类型; @GenericGenerator(name="myuuid",strategy="uuid")
                                                       @Generatedvalue(generator="myuuid")

           如果不想要生成在表中成员属性: @Transient, 可以使用@type(type="属性类型"),在get方法上面也能使用以上注解

   2.一对多的关系

        ① mappedby相当于inverse=true ,targetentity 相当于<one-to-many class=""> 中的class
            @OneToMany(targetentity=对方.class , mappedBy="本方在对方成员属性引用名")

       ②@ManytoOne(targetentity=对方.class )  @joincolumn(name="外键列名称") //指定外键列

       ③保存客户保存订单, 在customer中配置

                使用jpa提供注解  @OneToMany(cascade="")

                 在@OnetoMany注解下面: @cascade(cascadeType.注解类型);

                @cascade 中的 delete-orphan 过时了, 在 @OneToMany(orphanmoval=true)

    3. 注解: 多对多的关系 ,例子: .学生老师

         ① @ManytoMany 来配置多对多,只需要在一端配置中间表, 另一方mappeyby放弃外键维护权;
         ② @ManytoMany (targetentity=对方.class )
         ③使用jointable 描述中间表,并描述外键与student,teacher的映射关系 , name表名
              joincolumns 他是用来本方与中间表的映射关系,inversesjoincolumns=对方表主键对应
              jointable(name="",joincolumns={@joincolumn(name="")},inversesjoincolumns={@joincolumn(name="")})
        ④多对多级联删除: 前提:双向映射 两边都要有@cascade(all), 当删除一个数据时,他会找到另一个表,
             但另一个表又会关联了两个表,所以会把所有数据删除.

    4. 一对一关联关系 :  以人与身份证号

          ① 在任意一方,添加外键 @OnetoOne() @joincolumn(name="")
          ②主键映射 @Onetonone oprimarykeyjoincolumn 一边表配,
          ③ 在任何一方修改主键生成策略(name="my",strategy="foreign"
                parameters={@paramter(name="property" vlaue="另一张表的引用名")})就是参考另一张表的主键
               onetoone(mappedby="在另一张表中自己的引用名"
          注意: 保存根据参考主键

 

五.hibernate 检索方式

      1.导航对象图检索方式 : 通过在hibernate中进行映射关系,在hibernate操作时,可以用过导航方式得到,其关联的
                                          持久化对象信息 ,支持链式编程

      2.oid检索方式 : session.get() .load();

      3.hql检索方式 最常用 :  

          ①排序: from 类名 order by 类的成员属性 desc 默认asc
          ②条件检索: from 类名 where 类的成员属性>? session.setparameter(0,2000) 也可以使用setString()
                             ......where 类的成员属性>:xc setparameter(xc,值);
          ③分页查询,  setfirstresult();  setmaxresults();
          ④聚合: select count(*) from 表名
          ⑤分组: select from 表名 group by 成员属性中对方的引用名
          ⑥投影检索: 可以使用投影将部分属性封装到对象中。
               提供相应的构造方法,  select new 类名(name,id) from 类名
         ⑦多列查询:  Select name ,address from Customer; 得到的是 List<Object[]>结果
         ⑧命名检索: 将hql语句先定义, session.getnamequery(hqlname);
             1.如果有映射文件,那么当前hql是对哪一个实体进行操作.就在实体映射中,
                <query name="myhql"> from 类名

            2.使用注解来描述po的配置:  在类上面 @Namequery(name="myhql",query="from 类名 where name=?")
               Query query = session.getNamedQuery("myHql");query.setentity(0,参数); 方法只有参数是实体的时候才能用

    4.qbc检索方式 : 更加面向对象的检索方式.
        ①.通过session得到criteria对象  session.createcriteria(对象.class);
        ②设定条件  criteria实例  它的获取可以通过restrictons类提供静态,criteria的add方法用于添加查询条件判断
        ③调用list进行查询 criteria.list()
        ④排序 : criteria.addOrder(Order.desc("类的成员属性"))
        ⑤条件检索:  criteria.add(restrictons.like("属性","张_")); lt<  ge>  le<=  ge>=  eq=
            criteria.add(restrictons.and(restrictons.lt("属性","13432"),restrictons.eq("属性2","32"))
        ⑥分页检索: criteria.setfirstresult(这不是根据id来查的) criteria.setmaxresults();
        ⑦统计检索: criteria.setprojection(projections.rowcount())  sum,avg,rowcount统计总行
                 根据分组 criteria.setprojection(projections.projectionlist.add(projections.sum("money"))
                                                            .add(projections.groupproperty(""));
       ⑧离线查询: hibernate提供一个detachedcriteria对象,就可以在web层就将条件封装.在dao层就可得到criteria对象
               1.在web阶段detachedcriteria.forclass(对象.class).add(restrictons.like("属性","张_"));

                             得到detachedcriteria对象, 把他的引用传递到dao层
                 2. 在dao层:  dc.getexcutablecriteria(session).list();
        
   5.本地SQL检索方式:
          ①createSQLquery(SQL语句);
          ②.本地SQL命名查询:
             1.  hbm.xml中 <sql-query name="自定义名">
             2.  注解: @sqlresultsetmapping(name="自定义2",entities={@Entityresult(entitiyclass=类名.class,
                            fields={@fiedresult(name="",column="c_name"),....}) });类中的字段和表中的对应
                          @namednativequery(name="自定义名1" ,query="sql语句",resultsetmapping="自定义名2")
                                                           查询的结果集封装类型

                           session.getnamequery(自定义名1);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值