Hibernate得缓存

标题1 缓存的模拟

	public class CacheDemo {
		//缓存容器
		private static Map adminCache =new HashMap(); 
	
		static AdminInfo getAdminById(int id) {
			//先去缓存中看有没有数据
			String key=AdminInfo.class.getName()+id;
			AdminInfo admin=(AdminInfo)adminCache.get(key);
			
			//如果缓存中没有数据,则去数据库中查询
			if(admin==null) {
				admin= HibUtil.get(AdminInfo.class, id);
				adminCache.put(key,admin);
				System.out.println("从数据库中查询..");
			}
			else {
				System.out.println("从缓存中取的..");
			}
		
			return admin;
		}
		
		public static void update(AdminInfo admin) {
			HibUtil.update(admin);
			
			String key=admin.getClass().getName()+admin.getId();
			//adminCache.put(key,admin);
			adminCache.remove(key);
		}
		
		
		public static void delete(AdminInfo admin) {
			HibUtil.delete(admin);	
			String key=admin.getClass().getName()+admin.getId();
			adminCache.remove(key);
		}
		
		
		public static void main(String[] args) {
			System.out.println(	getAdminById(1));
			System.out.println(	getAdminById(1));
			
			AdminInfo admin=new AdminInfo();
			admin.setId(1);
			admin.setAdminName("赵强");
			update(admin);
			
	
			System.out.println(	getAdminById(1));
			System.out.println(	getAdminById(1));
			
			delete(admin);
			
			System.out.println(	getAdminById(1));
			System.out.println(	getAdminById(1));		
		}
	}
	
	
	主要有几点
	1) 缓存容器是全局的,对所有的线程都可见,共享
	2) 缓存的key 用的是 类名+ id
	3) 要注意在对象进行更新或删除的时候,进行缓存同步

标题2 hibernate 的一级缓存

hibernate 中的缓存有两种, 一级缓存,二级缓存

一级缓存:Session范围内的
二及缓存:SessionFactory 范围内的

	//例子: 一级缓存
			void test() {
				Session s=HibUtil.getSession();
				
				AdminInfo a1 =s.get(AdminInfo.class, 1);
				AdminInfo a2 =s.get(AdminInfo.class, 1);
				AdminInfo a3 =s.get(AdminInfo.class,2);
				AdminInfo a4 =s.get(AdminInfo.class, 1);
				AdminInfo a5 =s.get(AdminInfo.class, 2);
		
				HibUtil.closeSession();
			}

可以发现,最终就输出2条语句, 因为缓存了2个对象,其他的查询都是从缓存中取的

关于上面的一级缓存的说明
1)它的key 就是 AdminInfo.class +id
2)一级缓存的有效空间就是在Session范围内,生命周期特别短,不实用
3)save, update,saveOrUpdate,load,get,list,lock,iterator 等方法都会把对象添到一级缓存中
4)Session evict ,clear 等方法可以清除一级缓存
s.evice(admin) //只清除一个
s.clear() //清除所有
5) 一级缓存不能控制缓存对象的个数,如果有大量的对象要缓存,可能会造成内存溢出,注意处理

				void test() {
						Session s=HibUtil.getSession();	
						for(int i=0;i<999999999;i++) {
							
							if(i%200==0) {
								s.flush();  //同步一级缓存中的内容到数据库中
								s.clear();  //清除一缓存
							}
							AdminInfo admin=new AdminInfo();
							admin.setAdminName("用户_"+i);
							s.save(admin); 
						}
				
						HibUtil.closeSession();
					}

标题 3 hbiernate 的二级缓存

SessionFactory范围的
hibernate把缓存的管理交给了缓存框架去实现 (要有对应的jar包)

1) 导包
   /lib/optional/ehcache
    ehcache-2.10.6.jar
    hibernate-ehcache-5.4.14.Final.jar
    slf4j-api-1.7.25.jar
    
2) 在配置文件中声明启用二级缓存
   hibernate.cache.use_second_level_cache true   //默认是注起来的,而且后面是false,把它改成true
   

3) 生成统计信息( 在开发的时候用,是可选的 )
	
 hibernate.generate_statistics true   //默认是注起来的
  1. 选择缓存提供者
    #hibernate.cache.region.factory_class org.hibernate.cache.infinispan.InfinispanRegionFactory
    #hibernate.cache.region.factory_class org.hibernate.cache.infinispan.JndiInfinispanRegionFactory
    hibernate.cache.region.factory_class org.hibernate.cache.internal.EhCacheRegionFactory //这个地方配置文件和官方文档错了
    org.hibernate.cache.ehcache.internal.EhcacheRegionFactory 要写成这个样子

       #hibernate.cache.region.factory_class org.hibernate.cache.internal.SingletonEhCacheRegionFactory  
       #hibernate.cache.region.factory_class org.hibernate.cache.internal.NoCachingRegionFactory
    
  2. 指明哪个类要用二级缓存
    在主配置文件 hibernate.cfg.xml 中

       要写在下面
       
      或者写在映射文件中
       	
       		<class name="AdminInfo" >
       			<cache usage="read-write"/>  //写在这个位置
       			<id name="id">
       				<generator class="native" />
       			</id>
       			<property  name="password"   />
       			<property  name="note" />
       			<property  name="adminName" />
       		</class>
       		
        public static void main(String[] args) {
       		HibUtil.get(AdminInfo.class,1);
       		HibUtil.get(AdminInfo.class,1);
       		HibUtil.get(AdminInfo.class,2);
       		HibUtil.get(AdminInfo.class,1);
       		HibUtil.get(AdminInfo.class,1);
       		HibUtil.get(AdminInfo.class,1);
       		
       		//得到缓存相关的统计信息
       		Statistics total=  HibUtil.getSessionFactory().getStatistics();
       		System.out.println(total);
       		
       		System.out.println("二级缓存存入 "+ total.getSecondLevelCachePutCount()  +"次");  //2
       		System.out.println("二级缓命中 "+ total.getSecondLevelCacheHitCount()  +"次");  //4
       		System.out.println("二级缓存错过 "+ total.getSecondLevelCacheMissCount()  +"次");  //2
       	}
    

    通常来说,我们还要配置它的级配置文件
    ehcache.xml 可以从 project/etc 目录下找到

里面的主要配置

  <diskStore path="java.io.tmpdir"/>  //用来指定缓存的存放位置     <diskStore path="c:/cache/xxxx"/>  

<defaultCache
maxElementsInMemory=“10000” //内存中最多可以存多少对象
eternal=“false” //指定缓存是不是永不过期
timeToIdleSeconds=“120” //缓存的空闲时间(秒),过期以后会被删除
timeToLiveSeconds=“120” //缓存对象一共要存在多久
overflowToDisk=“true” //超过个数 (maxElementsInMemory 指定的个数)以后,是不是要往磁盘上存
diskPersistent=“true” //指的是jvm结束后,是不是要把缓存存到磁盘上
diskExpiryThreadIntervalSeconds=“60” //清除缓存的线程的轮循时间
/>

  我们可以尝试让它把缓存存到磁盘上 
     <diskStore path="c:/cache/xxxx"/>  内存中的对象超出以后,放在这个位置
		 <defaultCache
		        maxElementsInMemory="1"   //让内容中只能装下一个对象
		        eternal="false"
		        timeToIdleSeconds="120"
		        timeToLiveSeconds="120"
		        overflowToDisk="true"
		        />

关于二级缓存
1)哪些方法可以填充二级缓存
get ,save ( 不适合native主键的 ) , update,saveOrUpdate,load,list,iterator,Query ,Criteria 都会填充二级缓存
在查询的时候,昼量不要用 iterator 去处理数据,它可能存在N+1 次查询的问题

Query ,Criteria 缓存命中率比较低,而且可能要缓存的数量据也特别大, 在hibernate中默认是关闭的
可以用 在配置文件中配置 hibernate.cache.use_query_cache true
( 它会把查询条件做为key,查出来的结果做为value )

  1. 清除二级缓存
    //这是版本3
    HibUitl.getSessionFactory().evict(AdminInfo.class); //清除AdminInfo 对象的所有缓存
    HibUitl.getSessionFactory().evict(AdminInfo.class,1); //清除id为1的AdminInfo对象的缓存

//这是版本5
HibUtil.getSessionFactory().getCache().evictAll(); //清除所有
HibUtil.getSessionFactory().getCache().evict(AdminInfo.class);

  1. 下面的操作,会导致所有的二级缓存被清除
    Query q=s.createQuery("update admin set adminName= ‘xxx’ ");
    q.executeUpdate();
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值