添加redis缓存
2019-11-24 本文已影响0人
王侦
1.核心配置
<?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:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!-- Redis连接池的设置 -->
<bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
<!-- 控制一个pool可分配多少个jedis实例 -->
<property name="maxTotal" value="${redis.pool.maxActive}" />
<!-- 连接池中最多可空闲maxIdle个连接 ,这里取值为20,表示即使没有数据库连接时依然可以保持20空闲的连接,而不被清除,随时处于待命状态。 -->
<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.imooc.o2o.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.imooc.o2o.cache.JedisUtil" scope="singleton">
<property name="jedisPool">
<ref bean="jedisWritePool" />
</property>
</bean>
<!-- Redis的key操作 -->
<bean id="jedisKeys" class="com.imooc.o2o.cache.JedisUtil$Keys"
scope="singleton">
<constructor-arg ref="jedisUtil"></constructor-arg>
</bean>
<!-- Redis的Strings操作 -->
<bean id="jedisStrings" class="com.imooc.o2o.cache.JedisUtil$Strings"
scope="singleton">
<constructor-arg ref="jedisUtil"></constructor-arg>
</bean>
<!-- <!– Redis的Lists操作 –>
<bean id="jedisLists" class="com.imooc.o2o.cache.JedisUtil$Lists"
scope="singleton">
<constructor-arg ref="jedisUtil"></constructor-arg>
</bean>
<!– Redis的Sets操作 –>
<bean id="jedisSets" class="com.imooc.o2o.cache.JedisUtil$Sets"
scope="singleton">
<constructor-arg ref="jedisUtil"></constructor-arg>
</bean>
<!– Redis的HashMap操作 –>
<bean id="jedisHash" class="com.imooc.o2o.cache.JedisUtil$Hash"
scope="singleton">
<constructor-arg ref="jedisUtil"></constructor-arg>
</bean>-->
</beans>
一些配置参数放在redis.properties中:
redis.hostname=ip地址
redis.port=6379
redis.database=0
redis.pool.maxActive=100
redis.pool.maxIdle=20
redis.pool.maxWait=3000
redis.pool.testOnBorrow=true
web.xml中解析spring-*.xml,并且这里面的变量是可以共用的:
<servlet>
<servlet-name>spring-dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/spring-*.xml</param-value>
</init-param>
</servlet>
因此,在spring-dao.xml中配置了redis.properties可供spring-redis.xml使用:
<bean class="com.imooc.o2o.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>
2.获取线程池
public class JedisPoolWriper {
private JedisPool jedisPool;
public JedisPoolWriper(final JedisPoolConfig poolConfig, final String host, final int port) {
try {
jedisPool = new JedisPool(poolConfig, host, port);
} catch (Exception e) {
e.printStackTrace();
}
}
public JedisPool getJedisPool() {
return jedisPool;
}
public void setJedisPool(JedisPool jedisPool) {
this.jedisPool = jedisPool;
}
}
3.核心RedisUtil封装了redis操作
public class JedisUtil {
/**
* 操作Key的方法
*/
public Keys KEYS;
/**
* 对存储结构为String类型的操作
*/
public Strings STRINGS;
/**
* Redis连接池对象
*/
private JedisPool jedisPool;
public JedisPool getJedisPool() {
return jedisPool;
}
public void setJedisPool(JedisPoolWriper jedisPoolWriper) {
this.jedisPool = jedisPoolWriper.getJedisPool();
}
/**
* 从jedis连接池中获取jedis对象
* @return
*/
public Jedis getJedis() {
return jedisPool.getResource();
}
public class Keys {
/**
* 清空所有key
* @return
*/
public String flushAll() {
Jedis jedis = getJedis();
String data = jedis.flushAll();
jedis.close();
return data;
}
/**
* 删除keys对应的记录,可以是多个key
* @param keys
* @return
*/
public long del(String... keys) {
Jedis jedis = getJedis();
long count = jedis.del(keys);
jedis.close();
return count;
}
/**
* 判断key是否存在
* @param key
* @return
*/
public boolean exists(String key) {
Jedis jedis = getJedis();
boolean isExist = jedis.exists(key);
jedis.close();
return isExist;
}
/**
* 查找所有匹配给定模式的键
* @param pattern
* @return
*/
public Set<String> keys(String pattern) {
Jedis jedis = getJedis();
Set<String> set = jedis.keys(pattern);
jedis.close();
return set;
}
}
public class Strings {
/**
* 根据key获取记录
* @param key
* @return
*/
public String get(String key) {
Jedis jedis = getJedis();
String value = jedis.get(key);
jedis.close();
return value;
}
/**
* 添加记录,如果记录已存在则覆盖
* @param key
* @param value
* @return
*/
public String set(String key, String value) {
return set(SafeEncoder.encode(key), SafeEncoder.encode(value));
}
/**
* 添加记录,如果记录已存在将覆盖原有的value
* @param key
* @param value
* @return
*/
public String set(byte[] key, byte[] value) {
Jedis jedis = getJedis();
String status = jedis.set(key, value);
jedis.close();
return status;
}
}
}
4.使用Redis缓存
对象:不常变更的对象
@Service
public class AreaServiceImpl implements AreaService {
@Autowired
private AreaDao areaDao;
@Autowired
private JedisUtil.Keys jedisKeys;
@Autowired
private JedisUtil.Strings jedisStrings;
private static Logger logger = LoggerFactory.getLogger(AreaServiceImpl.class);
@Override
@Transactional
public List<Area> getAreaList() {
String key = AREALISTKEY;
List<Area> areaList = null;
ObjectMapper mapper = new ObjectMapper();
if (!jedisKeys.exists(key)) {
areaList = areaDao.queryArea();
String jsonString;
try {
jsonString = mapper.writeValueAsString(areaList);
jedisStrings.set(key, jsonString);
} catch (JsonProcessingException e) {
e.printStackTrace();
logger.error(e.getMessage());
throw new AreaOperationException(e.getMessage());
}
} else {
String jsonString = jedisStrings.get(key);
JavaType javaType = mapper.getTypeFactory().constructParametricType(ArrayList.class,
Area.class);
try {
areaList = mapper.readValue(jsonString, javaType);
} catch (IOException e) {
e.printStackTrace();
logger.error(e.getMessage());
throw new AreaOperationException(e.getMessage());
}
}
return areaList;
}
}