hibernate缓存与查询

来源:互联网 发布:snmp 网络拓扑 编辑:程序博客网 时间:2024/06/10 19:05
今天内容:
1.Hibernate缓存
   1.1 什么是缓存?
        缓存介于应用程序和物理数据源之间。
缓存是数据源数据的复制,应用程序运行过程中每次都是从缓存中读取数据,在特定的时间或者事件会同步缓存和物理数据源的信息。

1.2 为什么要用缓存?
            从web程序和服务器角度出发,降低应用访问服务器的次数,降低了服务器压力。
web程序从本地缓存读取数据速率更快,程序流畅度更高,用户体验度更好。     
   1.3  Hibernate的缓存
         针对的是持久化层,存储的是数据库数据的备份。
   1.4 Hibernate的缓存方式(2种)
        第一种:一级缓存(内置缓存,无法卸载的):  Session级别  :Session的缓存随着Session的消失而消失了。
      Session被关闭的情况下所有的Session缓存被清楚。 close()
/**
* Hibernate的一级缓存:Session级别的

* 第一次查询执行select语句,把查询的结果存储到session一级缓存中。
* 在同一次session中再次查询,不会再次发起sql语句,后续的查询结果会从session缓存中查找。

* session.evict(card1);//表示从session一级缓存中移除指定的对象,但是不会同步到数据库中
* session.clear();//表示移除session中所有装载的缓存对象和挂起的操作(saves,updates,deletes..)


* evict()和clear()把持久化的对象转化成了游离状态(托管状态)
*/
/**
* 快照:把set暂时存储起来了。
* 缓存:把set操作先存储缓存.

* 快照是缓存的备份。

* 1.Card card1 = session.get(Card.class, 1);查询把结果存储到缓存中
* 2.card1.setCardNum("11111111111111111111"); 把该操作的内容存储在缓存中,同时在快照中也存储一份
* 3.card1.setCardNum("2222222222222222"); 
*    把该操作的内容存储在缓存中,更新前先必须和以前的快照进行比对,
*      如果一致,直接持久化更新。
*      如果不一致,需要更新快照的数据,再去持久化。
*      
*  快照目的:   防止多次重复提交,重复发送sql语句 
*      
*/

        第二种:二级缓存(Hibernatem没有做处理,需要添加额外的包完成,常用Ehcache):  SessionFacotry级别 
          适用的情况:很少被修改或者是不是很重要的数据或者是偶尔出现并发问题的数据

        实现二级缓存的步骤:
 1.添加二级缓存包(hibernate下载库lib/optional/ehcache(3个))
 2.在hibernate.cfg.xml进行配置支持二级缓存(3个) hibernate下载库/project/etc/hibernate.properties中找到
       <!-- 配置二级缓存 -->
<!-- 开启二级缓存 -->
<property name="hibernate.cache.use_second_level_cache">true</property>
<!-- 查询二级缓存 -->
<property name="hibernate.cache.use_query_cache">true</property>
<!-- 指定二级缓存方式 -->
<property name="hibernate.cache.region.factory_class">org.hibernate.cache.internal.EhCacheRegionFactory</property>
                  3.配置二级缓存的配置文件ehcache.xml文件(hibernate下载库/project/etc/ehcache.xml)
 <!-- 配置二级磁盘缓存目录 -->
 <diskStore path="C:\cache"/>
<!--每一个实体类要缓存都是一个cache单元
  name:要缓存的类名(包名+类名)
  maxElementsInMemory:在内存中存放的最大对象的个数
  eternal:是否永久保存
  timeToIdleSeconds:缓存创建以后,最后一次访问的时间到失效的时间间隔
  timeToLiveSeconds:缓存创建以后到失效的时间
  overflowToDisk:超过内存存放对象的最大个数后,问超过的是否要存储在磁盘上
-->
<cache name="com.sky.pojo.Card"
maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="300"
timeToLiveSeconds="600"
overflowToDisk="true"
/>
                   4.配置缓存策略(4个):
           read-only:对于从来不修改的数据采用该策略   serizalible 
  read-write:对经常读但是很少修改的数据采用该策略  read committed      
  notstrict-read-write:对于极少被修改但是允许脏读的数据使用该策略。不保证数据库和缓存之间的一致性。
                       类似于read uncommitted
  transaction:仅仅用于受管理的坏境中使用。对经常读但是很少修改的数据,但是防止脏读和不可重复读数据。
              类似于  mysql默认级别 重复读repeatable read级别 
配置位置:写在要缓存的实体类的映射文件的class下。
                      <cache usage="read-only"/>

                  5.测试:  

* 二级缓存:SessionFactory级别,添加额外包配置的
* Session一级缓存(内存缓存)
* SesssionFactory二级缓存(磁盘缓存) 

* 如果所有缓存都存在,先去一级缓存(重要数据),再去二级缓存(不常修改或者是不重要的数据)查找

* 一级缓存:相对来说安全。  读取速度快(内存和磁盘读取速度)

2.Hibernate的4种查询方式  Query
    情况一:严格意义:5种方式
   1.oid方式:  get(T.class,id)/load(T.class,id)
   2.对象导航检索模式: User对象嵌套Address
    3.原生SQL语句查询:
    4.Hibernate查询语言(HQL):
    5.Criteria查询(QBC:Query  by  Criteria)

    情况二:一般情况: 3种
            1.原生SQL语句查询:
      1.1 基础查询:
       1.2 条件查询(举例1个):
       1.3 分页查询:
             2.Hibernate查询语言(HQL):
       3.Criteria查询(QBC:Query  by  Criteria)