学习品优购总结[八](广告管理与缓存解决方案)

广告类型及广告管理

广告类型:
(1)首页海报(轮播图)
(2)今日推荐
(3)猜你喜欢
(4)楼层广告
构建工程:
广告图片上传:
广告展示:

public List<TbContent> findByCategoryId(Long categoryId) {
	//根据广告分类ID查询广告列表		
	TbContentExample contentExample=new TbContentExample();
	Criteria criteria2 = contentExample.createCriteria();
	criteria2.andCategoryIdEqualTo(categoryId);
	criteria2.andStatusEqualTo("1");//开启状态		
	contentExample.setOrderByClause("sort_order");//排序		
	return  contentMapper.selectByExample(contentExample);
}

前端三目运算符:{{$index==0?'active':''}}

SpringDataRedis

目前的系统已经实现了广告后台管理和广告前台展示,但是对于首页每天有大量的人访问,每一次访问都要调用数据库查询广告,对数据库造成很大的访问压力,甚至是瘫痪。通常的做法有两种:一种是数据缓存(Redis)、一种是网页静态化。
Redis:
redis是一款开源的Key-Value数据库,运行在内存中,由ANSI C编写。企业开发通常采用Redis来实现缓存。Redis可以持久化数据到本地硬盘,有两种方式RDB和AOF。
Jedis:
Jedis不是数据库,是操作redis的官方API库。
Spring Data Redis:
Spring Data Redis是对redis操作的API库的封装,包含了(Jedis, JRedis, and RJC)
Spring-data-redis是spring大家族的一部分,提供了在srping应用中通过简单的配置访问redis服务,对reids底层开发包(Jedis, JRedis, and RJC)进行了高度封装,RedisTemplate提供了redis各种操作、异常处理及序列化,支持发布订阅,并对spring 3.1 cache进行了实现。
spring-data-redis针对jedis提供了如下功能:
1.连接池自动管理,提供了一个高度封装的“RedisTemplate”类
2.针对jedis客户端中大量api进行了归类封装,将同一类型操作封装为operation接口
ValueOperations:简单K-V操作
SetOperations:set类型数据操作
ZSetOperations:zset类型数据操作
HashOperations:针对map类型的数据操作
ListOperations:针对list类型的数据操作
SpringDataRedis准备工作:
1.pom.xml

	    <!-- 缓存 -->
	    <dependency> 
	    		  <groupId>redis.clients</groupId> 
	    		  <artifactId>jedis</artifactId> 
	    		  <version>2.8.1</version> 
	    </dependency> 
	    <dependency> 
	    		  <groupId>org.springframework.data</groupId> 
	    		  <artifactId>spring-data-redis</artifactId> 
	    		  <version>1.7.2.RELEASE</version> 
	    </dependency>	

2.建立redis-config.properties

	    redis.host=127.0.0.1 
	    redis.port=6379 
	    redis.pass= 
	    redis.database=0 
	    redis.maxIdle=300 
	    redis.maxWait=3000 
	    redis.testOnBorrow=true 

3.创建applicationContext-redis.xml

 <context:property-placeholder location="classpath*:properties/*.properties" />   
   <!-- redis 相关配置 --> 
   <bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig">  
     <property name="maxIdle" value="${redis.maxIdle}" />   
     <property name="maxWaitMillis" value="${redis.maxWait}" />  
     <property name="testOnBorrow" value="${redis.testOnBorrow}" />  
   </bean>  
   <bean id="JedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory" 
       p:host-name="${redis.host}" p:port="${redis.port}" p:password="${redis.pass}" p:pool-config-ref="poolConfig"/>  
   
   <bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">  
     <property name="connectionFactory" ref="JedisConnectionFactory" />  
   </bean>  

maxIdle :最大空闲数
maxWaitMillis:连接时的最大等待毫秒数
testOnBorrow:在提取一个jedis实例时,是否提前进行验证操作;如果为true,则得到的jedis实例均是可用的;
4.操作:
(1)值类型操作

	//存储
	public void setValue(){
		redisTemplate.boundValueOps("name").set("itcast");		
	}	
	//取值
	public void getValue(){
		String str = (String) redisTemplate.boundValueOps("name").get();
		System.out.println(str);
	}
	//删除
	public void deleteValue(){
	redisTemplate.delete("name");;
	}

(2) Set类型操作

   		//存值
   		public void setValue(){
    		redisTemplate.boundSetOps("nameset").add("曹操");		
    		redisTemplate.boundSetOps("nameset").add("刘备");}
		//取值
        public void getValue(){
            Set nameSet = redisTemplate.boundSetOps("nameSet").members();
            System.out.println(nameSet);
        }
		//移除一个值
	    public void removeValue(){
	        redisTemplate.boundSetOps("nameSet").remove("孙权");
	    }
		//全部删除
	    public void removeAllValue(){
	        redisTemplate.delete("nameSet");
	    }

(3)List类型操作
右压栈:后添加的对象排在后边

	public void testSetValue1(){		
		redisTemplate.boundListOps("namelist1").rightPush("刘备");
		redisTemplate.boundListOps("namelist1").rightPush("关羽");
		redisTemplate.boundListOps("namelist1").rightPush("张飞");		
	}
	//显示右压栈集合
	public void testGetValue1(){
		List list = redisTemplate.boundListOps("namelist1").range(0, 10);//range(0,-1)是取全部
		System.out.println(list);
	}
运行结果:
[刘备, 关羽, 张飞]

左压栈:后添加的对象排在前边

	public void testSetValue2(){		
		redisTemplate.boundListOps("namelist2").leftPush("刘备");
		redisTemplate.boundListOps("namelist2").leftPush("关羽");
		redisTemplate.boundListOps("namelist2").leftPush("张飞");		
	}
	
	/**
	 * 显示左压栈集合
	 */
	@Test
	public void testGetValue2(){
		List list = redisTemplate.boundListOps("namelist2").range(0, 10);
		System.out.println(list);
	}
运行结果:
[张飞, 关羽, 刘备]

根据索引查询元素:

	//查询集合某个元素
	public void testSearchByIndex(){
		String s = (String) redisTemplate.boundListOps("namelist1").index(1);
		System.out.println(s);
	}
	//移除集合某个元素
	public void testRemoveByIndex(){
		redisTemplate.boundListOps("namelist1").remove(1, "关羽");
	}

(4)Hash类型操作

    //存入值
    public void testSetValue(){
    		redisTemplate.boundHashOps("namehash").put("a", "唐僧");
    		redisTemplate.boundHashOps("namehash").put("b", "悟空");
    		redisTemplate.boundHashOps("namehash").put("c", "八戒");
    		redisTemplate.boundHashOps("namehash").put("d", "沙僧");
    	}
	//提取所有的KEY
	public void testGetKeys(){
		Set s = redisTemplate.boundHashOps("namehash").keys();		
		System.out.println(s);		
	}
    运行结果:
    [a, b, c, d]
    //提取所有的值
	public void testGetValues(){
		List values = redisTemplate.boundHashOps("namehash").values();
		System.out.println(values);		
	}
    运行结果:
    [唐僧, 悟空, 八戒, 沙僧]
    //根据KEY提取值
	public void testGetValueByKey(){
		Object object = redisTemplate.boundHashOps("namehash").get("b");
		System.out.println(object);
	}
    运行结果:
    悟空
    //根据KEY移除值
	public void testRemoveValueByKey(){
		redisTemplate.boundHashOps("namehash").delete("c");
	}
    运行后再次查看集合内容:
    [唐僧, 悟空, 沙僧]
    //获取所有键值对
    Map nameHash = redisTemplate.boundHashOps("nameHash").entries();
    /*Iterator iterator = nameHash.entrySet().iterator();
    while (iterator.hasNext()){
        System.out.println(iterator.next());
    }*/
    /*Set set = nameHash.entrySet();
    for (Object o : set) {
        System.out.println(o);
    }*/
    Set set = nameHash.keySet();
    for (Object o : set) {
        System.out.println(o+"="+nameHash.get(o));
    }

缓存广告数据

	@Autowired
	private RedisTemplate redisTemplate;	

	public List<TbContent> findByCategoryId(Long categoryId) {
		List<TbContent> contentList= (List<TbContent>) redisTemplate.boundHashOps("content").get(categoryId);
		if(contentList==null){
			//根据广告分类ID查询广告列表		
			TbContentExample contentExample=new TbContentExample();
			Criteria criteria2 = contentExample.createCriteria();
			criteria2.andCategoryIdEqualTo(categoryId);
			criteria2.andStatusEqualTo("1");//开启状态
			contentExample.setOrderByClause("sort_order");//排序
			contentList = contentMapper.selectByExample(contentExample);//获取广告列表
			redisTemplate.boundHashOps("content").put(categoryId, contentList);//存入缓存 
		}
		return  contentList;
	}

广告数据缓存更新

当从数据库查询出来数据,保存到redis之后,数据库就不在查询了,只操作redis的数据,和数据库没有关系了,但是如果数据库的数据更新了,redis是不知道了,这个时候redis中的数据和数据库中的数据就不一致了,所以就会出错,这时在增删改数据库中的数据时都需要重新缓存。
更新redis数据的方案
在数据库增加、更新、删除数据的时候,删除redis中的缓存数据,在重新查询数据库的时候,就会添加到redis中。
新增广告后清除缓存:redisTemplate.boundHashOps("content").delete(content.getCategoryId());
更新广告后清楚缓存:

	//查询修改前的分类Id
	Long categoryId = contentMapper.selectByPrimaryKey(content.getId()).getCategoryId();
	redisTemplate.boundHashOps("content").delete(categoryId);
	contentMapper.updateByPrimaryKey(content);
	//如果分类ID发生了修改,清除修改后的分类ID的缓存
	if(categoryId.longValue()!=content.getCategoryId().longValue()){
		redisTemplate.boundHashOps("content").delete(content.getCategoryId());
	}	

如果这个广告是从分类1改变到分类2,那么这两个分类都进行了更新所以都要删除缓存,要不然酚类2中查询不到新加进来的广告。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值