shop--13.升级--Redis缓存技术
1.引入redis的jar包
<!--redis客户端:jedis-->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.9.0</version>
</dependency>
2.redis.properties配置文件
redis.hostname=127.0.0.1 redis.port=6379 redis.database=0 redis.pool.maxActive=100 redis.pool.maxIdle=20 redis.pool.maxWait=3000 redis.pool.testOnBorrow=true
3.在spring-dao.xml下引入redis.properties配置文件中相关的key-value
<!-- 1.配置数据库相关参数properties的属性:${url} -->
<!--<context:property-placeholder location="classpath:jdbc.properties"/>-->
<bean class="com.shop.util.EncryptPropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:jdbc.properties</value>
<value>classpath:redis.properties</value>
</list>
</property>
<property name="fileEncoding" value="utf-8"/>
</bean>
4.编写JedisPoolWriper类
/**
* 强指定redis的JedisPool接口构造函数,这样才能在centos成功创建jedispool
* Created by Skye on 2018/5/13.
*/
public class JedisPoolWriper {
//Redis连接池对象
private JedisPool jedisPool;
public JedisPoolWriper(final JedisPoolConfig jedisPoolConfig, final String host, final int port){
jedisPool = new JedisPool( jedisPoolConfig, host, port );
}
public JedisPool getJedisPool() {
return jedisPool;
}
public void setJedisPool(JedisPool jedisPool) {
this.jedisPool = jedisPool;
}
}
5.编写JedisUtil工具类
6.sprins-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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--redis连接池设置-->
<bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
<!--控制一个连接池可分配多少个jedis实例-->
<property name="maxTotal" value="${redis.pool.maxActive}" />
<!--连接池中最多可空闲maxIdle个连接,-->
<property name="maxIdle" value="${redis.pool.maxIdle}" />
<!--最大等待时间-->
<property name="maxWaitMillis" value="${redis.pool.maxWait}" />
<!--在获取连接时候检查有效性-->
<property name="testOnBorrow" value="${redis.pool.testOnBorrow}" />
</bean>
<!--创建redis连接池,并做相关配置-->
<bean id="jedisWritePool" class="com.shop.cache.JedisPoolWriper"
depends-on="jedisPoolConfig">
<constructor-arg index="0" ref="jedisPoolConfig" />
<constructor-arg index="1" value="${redis.hostname}" />
<constructor-arg index="2" value="${redis.port}" type="int" />
</bean>
<!--创建Redis工具类,封装好Redis的连接以进行相关的操作-->
<bean id="jedisUtil" class="com.shop.cache.JedisUtil"
scope="singleton">
<property name="jedisPool">
<ref bean="jedisWritePool" />
</property>
</bean>
<!--Redis的key操作-->
<bean id="jedisKeys" class="com.shop.cache.JedisUtil$KEYS"
scope="singleton">
<constructor-arg ref="jedisUtil"></constructor-arg>
</bean>
<!--Redis的String操作-->
<bean id="jedisStrings" class="com.shop.cache.JedisUtil$STRINGS"
scope="singleton">
<constructor-arg ref="jedisUtil"></constructor-arg>
</bean>
<bean id="jedisLists" class="com.shop.cache.JedisUtil$LISTS"
scope="singleton">
<constructor-arg ref="jedisUtil"></constructor-arg>
</bean>
<bean id="jedisSets" class="com.shop.cache.JedisUtil$SETS"
scope="singleton">
<constructor-arg ref="jedisUtil"></constructor-arg>
</bean>
<bean id="jedisHash" class="com.shop.cache.JedisUtil$HASH"
scope="singleton">
<constructor-arg ref="jedisUtil"></constructor-arg>
</bean>
</beans>
7.在项目中引入redis缓存技术
在需要进行redis缓存的service层中先@Autowired引入jedis的Keys和Strings
AreaServiceImpl中将之前getAreaList()方法只是简单的从AreaDao中获取AreaList改为从缓存中获取,如果不存在的话,在重新从数据库获取,并加入到redis的key-value中去
为了使得数据库内容修改后redis中的值也进行修改,所以将保存区域列表的关键字常量值放在AreaService的接口中,并且重新写一个Cache的Service将之前保存的该关键字相关的key-value都删掉
AreaService接口
public interface AreaService {
//保存区域列表信息的key
public static final String AREALISTKEY = "arealist";
/**
* 获取区域列表
* @return
*/
List<Area> getAreaList();
}
AreaServiceImpl
@Service
public class AreaServiceImpl implements AreaService {
@Autowired
private AreaDao areaDao;
@Autowired
private JedisUtil.Keys jedisKeys;
@Autowired
private JedisUtil.Strings jedisStrings;
@Override
@Transactional
public List<Area> getAreaList() {
String key = AREALISTKEY;
List<Area> areaList = null;
ObjectMapper objectMapper = new ObjectMapper();
if(!jedisKeys.exists( key )){
areaList = areaDao.queryArea();
String jsonString = null;
try {
jsonString = objectMapper.writeValueAsString( areaList );
} catch (JsonProcessingException e) {
e.printStackTrace();
throw new RuntimeException( e.getMessage() );
}
jedisStrings.set( key, jsonString );
} else{
String jsonString = jedisStrings.get( key );
JavaType javaType = objectMapper.getTypeFactory().constructParametricType( ArrayList.class, Area.class );
try {
areaList = objectMapper.readValue(jsonString, javaType);
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException( e.getMessage() );
}
}
return areaList;
}
}
ShopCategoryService接口
public interface ShopCategoryService {
public static final String SCLISTKEY = "shopcategorylist";
/**
* 根据查询条件获取店铺类别列表
* @param shopCategoryCondition
* @return
*/
List<ShopCategory>getShopCategoryList(ShopCategory shopCategoryCondition);
}
ShopCategoryImpl
@Service
public class ShopCategoryServiceImpl implements ShopCategoryService {
@Autowired
private ShopCategoryDao shopCategoryDao;
@Autowired
private JedisUtil.Keys jedisKeys;
@Autowired
private JedisUtil.Strings jedisStrings;
@Override
@Transactional
public List<ShopCategory> getShopCategoryList(ShopCategory shopCategoryCondition) {
String key = SCLISTKEY;
List<ShopCategory> shopCategoryList = null;
ObjectMapper objectMapper = new ObjectMapper( );
if(shopCategoryCondition == null){
//若查询条件为空,则拼接出所有首页大类,即parentId为空的店铺类别
key = key + "_allfirstlevel";
} else if(shopCategoryCondition != null
&& shopCategoryCondition.getParent() != null
&& shopCategoryCondition.getParent().getShopCategoryId() != null){
//若parentId不为空,则列出parentId不为空的所有子类
key = key + "_parent" + shopCategoryCondition.getParent().getShopCategoryId();
} else if(shopCategoryCondition.getShopCategoryId() != null){
//列出所有子类,不管属于哪个类别
key = key + "_allsecondlevel";
}
if(!jedisKeys.exists( key )){
shopCategoryList = shopCategoryDao.queryShopCategory( shopCategoryCondition );
String jsonString;
try {
jsonString = objectMapper.writeValueAsString( shopCategoryList );
} catch (JsonProcessingException e) {
e.printStackTrace();
throw new RuntimeException( e.getMessage() );
}
jedisStrings.set( key, jsonString);
} else{
String jsonString = jedisStrings.get( key );
JavaType javaType = objectMapper.getTypeFactory().constructParametricType( ArrayList.class, ShopCategory.class );
try {
shopCategoryList = objectMapper.readValue(jsonString, javaType);
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException( e.getMessage() );
}
}
return shopCategoryList;
}
}
HeadLineService接口
public interface HeadLineService {
public static final String HEADLINELISTKEY = "headlinelist";
/**
* 根据查询条件返回头条列表
* @param headLineCondition
* @return
*/
List<HeadLine> getHeadLineList(HeadLine headLineCondition);
}
HeadLineImpl
@Service
public class HeadLineServiceImpl implements HeadLineService {
@Autowired
HeadLineDao headLineDao;
@Autowired
private JedisUtil.Keys jedisKeys;
@Autowired
private JedisUtil.Strings jedisStrings;
@Override
@Transactional
public List<HeadLine> getHeadLineList(HeadLine headLineCondition) {
String key = HEADLINELISTKEY;
List<HeadLine> headLineList = null;
ObjectMapper objectMapper = new ObjectMapper( );
if(headLineCondition != null && headLineCondition.getStatus() != null){
key = key + "_" + headLineCondition.getStatus();
}
if(!jedisKeys.exists( key )){
headLineList = headLineDao.queryHeadLine( headLineCondition );
String jsonString;
try {
jsonString = objectMapper.writeValueAsString( headLineList );
} catch (JsonProcessingException e) {
e.printStackTrace();
throw new RuntimeException( e.getMessage() );
}
jedisStrings.set( key, jsonString);
} else{
String jsonString = jedisStrings.get( key );
JavaType javaType = objectMapper.getTypeFactory().constructParametricType( ArrayList.class, HeadLine.class );
try {
headLineList = objectMapper.readValue(jsonString, javaType);
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException( e.getMessage() );
}
}
return headLineList;
}
}
在数据库修改之后,要将Redis中存储的缓存删除掉
CacheService接口
public interface CacheService {
/**
* 依据key前缀,删除匹配该模式下的所有key-value
* 如传入shopcategory,则shopcategory_allfirstlevel等以shopcategory开头的key_value都会被清空
* @param keyPrefix
*/
void removeFromCache(String keyPrefix);
}
CacheServiceImpl
@Service
public class CacheServiceImpl implements CacheService {
@Autowired
JedisUtil.Keys jedisKeys;
@Override
public void removeFromCache(String keyPrefix) {
Set<String> keySet = jedisKeys.keys( keyPrefix + "*" );
for(String key : keySet){
jedisKeys.del( key );
}
}
}

浙公网安备 33010602011771号