在分布式项目中使用SpringDataredis(数据缓存)
在做前端的广告展示的时候,每天都有大连的人访问,对数据库造成很大的访问压力,甚至是瘫痪。又两种办法解决,第一是数据缓存,第二是网页静态化,今天我们选择第一种,首先我们来了解一下redis。
Redis
redis是一种开源的key-Value数据库,在内存中运行,企业开发通常用它来实现缓存。
SpringDataRedis
Spring-data-redis 是spring中的一部分,提供了在srping应用中通过简单的配置访问redis服务,对reids底层开发包(Jedis, JRedis, and RJC)进行了高度封装,RedisTemplate提供了redis各种操作、异常处理及序列化,支持发布订阅,并对spring 3.1 cache进行了实现。
使用中所用到的依赖
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.9</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.2.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>4.2.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>4.2.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>4.2.4.RELEASE</version>
</dependency>
<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>
</dependencies>
需要的配置文件
在main/resources/下创建applicationContext-redis.xml和redis-config.properties文件
applicationContext-redis.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:dubbo="http://code.alibabatech.com/schema/dubbo" xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<context:property-placeholder location="classpath*:*.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>
</beans>
redis-config.properties:
redis.host=192.168.200.128
redis.port=6379
redis.pass=
redis.database=0
redis.maxIdle=300
redis.maxWait=3000
redis.testOnBorrow=true
maxIdle :最大空闲数
maxWaitMillis:连接时的最大等待毫秒数
testOnBorrow:在提取一个jedis实例时,是否提前进行验证操作;如果为true,则得到的jedis
在项目中使用的注意事项
因为我们在查数据是先去redis中查询,如果redis中没有数据,那么回去数据库中查找,找到数据后,将数据存入到redis中,那么,在实现后台代码时,我们一定要记得在增删改时,在改变表的同时,也要将redis清空,不然就会出现,数据库改变了,但是展示出来的数据依然是原来的数据,就是因为没有将redis清空。
@Autowired
private RedisTemplate redisTemplate;
//添加
@Override
public void add(Content content) {
//1.添加了广告 到mysql数据库
contentDao.insert(content);
//2.根据分类id到redis中删除对应分类的广告集合
redisTemplate.boundHashOps(Constants.CONTENT_LIST_REDIS).delete(content.getCategoryId());
}
//修改
@Override
public void update(Content content) {
//1.根据广告的id 到mysql中查询原来的广告对象
Content oldContent = contentDao.selectByPrimaryKey(content.getId());
//2.根据原来广告对象中的分类id到redis中删除对应的广告集合
redisTemplate.boundHashOps(Constants.CONTENT_LIST_REDIS).delete(oldContent);
//3.根据传入的最新的广告分类对象的id删除redis中对应的广告数据集合
redisTemplate.boundHashOps(Constants.CONTENT_LIST_REDIS).delete(content.getCategoryId());
//4.将新的广告集合对象跟新到mysql
contentDao.updateByPrimaryKeySelective(content);
}
//删除
@Override
public void delete(Long[] ids) {
if (ids != null){
for (Long id : ids) {
Content content = contentDao.selectByPrimaryKey(id);
//根据广告对象中的分类id删除redis中的对应的广告集合数据
redisTemplate.boundHashOps(Constants.CONTENT_LIST_REDIS).delete(content.getCategoryId());
contentDao.deleteByPrimaryKey(id);
}
}
}
//查找数据库中的数据
@Override
public List<Content> findByCategoryId(Long categoryId) {
ContentQuery query = new ContentQuery();
ContentQuery.Criteria criteria = query.createCriteria();
criteria.andCategoryIdEqualTo(categoryId);
List<Content> list = contentDao.selectByExample(query);
return list;
}
//查找redois中的数据
@Override
public List<Content> findByCategoryFormRedis(Long categoryId) {
//1.根据分类的id 到redis中取数据
List<Content> contentList =(List<Content>) redisTemplate.boundHashOps(Constants.CONTENT_LIST_REDIS).get(categoryId);
//2.如果redis中没有数据 到数据库中去取
if (contentList == null){
//3.如果数据库中获取到数据,存入redis中一份
contentList=findByCategoryId(categoryId);
redisTemplate.boundHashOps(Constants.CONTENT_LIST_REDIS).put(categoryId,contentList);
}
return contentList;
}