缓存

缓存

 

缓存的作用主要用来提高性能、优化查询,可以简单的理解成一个Map;使用缓存涉及到三个操作:把数据放入缓存、从缓存中获取数据、删除缓存中的无效数据。

 

可以通过下面这个小例子理解缓存

package com.hbsi.hibernate;

import java.util.HashMap;

import java.util.Map;

import com.hbsi.domain.User;

public class CacheDemp {

    public static void main(String[]args) {

       // TODO Auto-generatedmethod stub

       getUser(1);//第一个人要查询id是1的用户,查询数据库

       //getUser(1);//第二个人要查询id是1的用户,直接从map集合中获取到

       updateUser(1);//数据更新时,缓存中原本的无效数据会被删除

       getUser(1);//查询数据库

    }

    //map用来暂时保存前面查出来的键值对

    private static Map map=newHashMap();

    public static User getUser(int id){

       //map(key--value     vaule:User对象  key:构建key.类型名+id)

       //构建键

       Stringkey=User.class.getName();//得到类型名

       key=key+id;

       User user=(User) map.get(key);//从缓存中取数据

       if(user!=null){

           return user;

       }else{

           getFromDB();

           map.put(key,user);//向缓存中存入数据

           return user;

       }

    }

 

    public static User getFromDB(){

       //从数据库中去访问数据

       return null;

    }

   

    public static void updateUser(int id){

       updateDB(id);//要更新数据库中指定id的那个用户数据

       Stringkey=User.class.getName()+id;

       map.remove(key);//一旦数据库中的数据更新了,就将缓存中的无效数据删除

      

    }

    public static void updateDB(int id){

       //更新数据库中的数据

    }

}

 

Hibernate内部缓存的分析:

1、  一级缓存:session级别的缓存

一级缓存的缺陷:没有保护,不能控制缓存的数量,直到内存溢出。在批量处理时有问题。作用范围比较小,缓存内容不能在session中共享,声明周期取决session

 

证明一级缓存的存在:

 

public static User getUser(int id){

       Session session=null;

           try{

           session=HibernateUtil.getSession();

           //只显示一条查询语句,说明一级缓存存在

           User user=(User) session.get(User.class, id);

           System.out.println("----------------");

           user=(User)session.get(User.class, id);//从缓存中得到数据,所有没有对应select语句

           return user;

       }finally{

           if(session!=null){

              session.close();

           }

       }

}

 

public static User getUser(int id){

       Session session=null;

       //session关闭了,缓存中的内容也被清除了,所有会出现两条select语句

       try{

           session=HibernateUtil.getSession();

           User user=(User) session.get(User.class, id);

       }finally{

           if(session!=null){

              session.close();

           }

       }

       try{

           session=HibernateUtil.getSession();

           User user=(User) session.get(User.class, id);

           return user;

       }finally{

           if(session!=null){

              session.close();

           }

       }

    }

通过两个例子的对比可以证明一级缓存的存在

 

 

什么时候会将数据放入缓存?

Save,update,saveOrUpdate,load,get,list,iterate,lock

什么时候会从缓存中取数据?

查询的时候(get()和load()):

先去缓存中取查找数据,如果缓存中没有在去数据库中取查询

 

Hqi的这个query这个接口调用list方法,并不从缓存中取提取数据,直接访问数据库,从数据库中得到相应的结果,但是它取出来的数据会存入缓存中

String sql="from User where id="+id;

           Query q=session.createQuery(sql);

           q.list();

Criteria:不从缓存中提取数据

 

清除缓存:

session.evict(user);//清除一级缓存中指定的对象

session.clear();//清除一级缓存中的所有对象

 

 

2、  二级缓存:sessionFactory级别的缓存

(1)在hibernate.cfg.xml中配置二级缓存,主要告诉hibernate第三方的相应的缓存的提供者是谁

<!-- 配置二级缓存 ,这个属性的值设置为真表示要打开二级缓存,这个属性的默认值为true,所以可以不配置-->

       <property name="hibernate.cache.use_second_level_cache">true</property>

(2)<!-- 第三方的二级缓存的提供者是谁 -->

       <property name="hibernate.cache.provider_class">org.hibernate.cache.OSCacheProvider</property>

Hibernate内部没有实现这种复杂的缓存

(3)导入缓存的实现所需要的jar包:

hibernate-distribution-3.6.8.Final\lib\optional\oscache下的jar包

(4)将oscache所需要的配置文件oscache.properties拷贝到src下,文件的名字和路径不要改变,否则找不到

(5)默认情况下类的对象都不放入二级缓存中,所有要告诉hibernate哪些类是要放入缓存的

方法一:

<!-- 指定哪些类的对象要放入缓存 -->

       <class-cache usage="read-only"class="com.hbsi.domain.User"/>

    usage="read-only"为缓存的使用策略,值有多种

read-only:只读的,效率最高,但是有一个限制,如果缓存中的对象被更新的话,就会抛异常

read-write:可读写的,可以并发的修改数据,可以保证缓存中的数据是正确的,效率会受到相应的影响

nonstrict-read-writer:不严格限制的可读写,不对数据进行加锁,效率稍微高一些,可能会出现一些无效数据

transactional:事务型的缓存,可以回滚缓存中的数据,一般的缓存框架都不支持此功能

方法二:在类的映射文件中告诉hibernate

<class name="User"table="user">

       <cache usage="read-write"/>

。。。。。。。。。

//测试二级缓存是否存在

      

       try{

           session=HibernateUtil.getSession();

           User user=(User) session.get(User.class, id);

           user=(User) session.get(User.class, id);//从一级缓存中查询

       }finally{

           if(session!=null){

              session.close();

           }

       }

       try{

           session=HibernateUtil.getSession();

           //只显示一条查询语句,说明二级缓存存在

    //先从一级缓存中查,但是现在一级缓存中没有所有去二级缓存中找

           User user=(User) session.get(User.class, id);

           return user;

       }finally{

           if(session!=null){

              session.close();

           }

       }

    }

 

在Sataisticsst=SessionFactory.getStatistics()//得到缓存的统计信息

在配置文件中配置:

<!-- 在工作的过程中产生各种的统计信息,对调试有很大的帮助 -->

       <property name="hibernate.generate_statistics"> true</property>

//得到统计信息

       Statistics st=HibernateUtil.getSessionFactory().getStatistics();

       System.out.println(st);

 

得到的信息为:Statistics[start time=1324006115531,sessionsopened=3,sessions closed=3,transactions=1,successful transactions=1,optimisticlock failures=0,flushes=1,connections obtained=2,statementsprepared=2,statements closed=2,second level cache puts=1,second level cachehits=1,second level cache misses=1,entities loaded=1,entitiesupdated=0,entities inserted=1,entities deleted=0,entities fetched=0,collectionsloaded=0,collections updated=0,collections removed=0,collectionsrecreated=0,collections fetched=0,queries executed to database=0,query cacheputs=0,query cache hits=0,query cache misses=0,max query time=0]

 

HibernateUtil.getSessionFactory().evict(User.class);//清除二级缓存

只能清除某一个类型的数据,没有clear方法

 

什么时候会把数据放到二级缓存中?

查询时缓存中没有就会放入

不适应用native主键生成器生成的,如果使用native主键生成器生成的,在调用save()时就不会把数据放入二级缓存中

Python网络爬虫与推荐算法新闻推荐平台:网络爬虫:通过Python实现新浪新闻的爬取,可爬取新闻页面上的标题、文本、图片、视频链接(保留排版) 推荐算法:权重衰减+标签推荐+区域推荐+热点推荐.zip项目工程资源经过严格测试可直接运行成功且功能正常的情况才上传,可轻松复刻,拿到资料包后可轻松复现出一样的项目,本人系统开发经验充足(全领域),有任何使用问题欢迎随时与我联系,我会及时为您解惑,提供帮助。 【资源内容】:包含完整源码+工程文件+说明(如有)等。答辩评审平均分达到96分,放心下载使用!可轻松复现,设计报告也可借鉴此项目,该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的。 【提供帮助】:有任何使用问题欢迎随时与我联系,我会及时解答解惑,提供帮助 【附带帮助】:若还需要相关开发工具、学习资料等,我会提供帮助,提供资料,鼓励学习进步 【项目价值】:可用在相关项目设计中,皆可应用在项目、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面,可借鉴此优质项目实现复刻,设计报告也可借鉴此项目,也可基于此项目来扩展开发出更多功能 下载后请首先打开README文件(如有),项目工程可直接复现复刻,如果基础还行,也可在此程序基础上进行修改,以实现其它功能。供开源学习/技术交流/学习参考,勿用于商业用途。质量优质,放心下载使用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值