我们可以做的更好2
加入缓存技术,使用Redis数据库
1、首先在pom.xml中加入,jedis是java对redis操作的jar包
<!-- redis -->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.9.0</version>
</dependency>
2、创建spring-redis.xml配置文件
2.1、连接池配置,配置jar包中的类,jedisPoolConfig
<!-- Redis连接池的配置 -->
<bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
<!-- 控制一个pool可分配多少个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>
2.2、创建redis.properties

因为我们在web.xml里把所有的spring文件下的spring打头的所有xml文件都统一的load进来了,加到相应的spring的配置当中。因此这些xml文件中配置是共享的。我们在spring-dao里做的配置同样spring-redis里也能共享。所以为了spring-redis.xml能读取得到redis.properties里的信息,我们不需要再spring-redis.xml里配置EncryptPropetryPlaceholderConfigurer的bean。直接在spring-dao的配置加上redis.properties就行了。
web.xml

spring-dao.xml,这两个配置就会加载进来供我们四个xml使用

3、创建jedisWritePool
这里redis包冲突了,把maven下的redis删除项目重新update就行了。不然找不到JedisPool
public class JedisPoolWriper {
//redis连接池对象
private JedisPool jedisPool;
/**
* 构造器
* @param poolConfig 连接池配置相关信息
* @param host redis数据库位于哪个主机ip
* @param port 访问redis数据库的端口
*/
public JedisPoolWriper(final JedisPoolConfig poolConfig, final String host, final int port) {
try {
jedisPool = new JedisPool(poolConfig, host, port);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 获取Redis连接池对象
* @return
*/
public JedisPool getJedisPool() {
return jedisPool;
}
/**
* 注入Redis连接池对象
* @param jedisPool
*/
public void setJedisPool(JedisPool jedisPool) {
this.jedisPool = jedisPool;
}
}
bean配置
<!-- 创建Redis连接池,并做相关的配置 -->
<!-- 这里可能会觉得奇怪,没有引入数据库的Properties文件,
却可以直接获取到redis.hostname,redis.port等属性,
原因在于web.xml中对contextconfiguration配置时引入了全部的spring-*.xml文件,
所以这个spring-redis.xml可以共享spring-dao.xml中的配置 -->
<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>
4、将连接池运用到工具类里
这个工具类就是从连接池中获取jedis对象,然后进行一系列key操作,strings操作,set操作,list操作,sortset操作。。。。是我写过最长的一个java类。。。自己看文件。。。还有spring-redis文件里的bean。
5、保存不常更新的数据
有三种不常更新的数据,分别是区域信息,头条信息,店铺类别信息。
需要在service层的getAreaList方法里修改
1、流程是让这些数据先去redis里获取,
2、如果获取不到就去后台里获取
3、再把相关数据更新到redis里。
1、先注入jedis工具操作类和一个被所有成员变量共享的键变量
@Autowired
private JedisUtil.Keys jedisKeys;
@Autowired
private JedisUtil.Strings jedisStrings;
private static String AREALISTKEY = "arealist";
@Override
@Transactional
public List<Area> getAreaList() {
String key = AREALISTKEY; // 要查找jedis数据的键
List<Area> areaList = null; // 要返回的前台的数据
// 因为我们是用jedis的Strings类型存储的,所以值及
// list集合需要转换为String类型然后才能存,这里就是要
// ObjectMapper来将对象转换为json字符串
ObjectMapper mapper = new ObjectMapper();
// 如果redis数据库中没有存储区域信息,则先从持久化数据库中获取的区域信息
// 然后进行类型转换,最后添加到redis数据库中
// 然后才从redis中获取数据转换再返回前台
if (!jedisKeys.exists(key)) {
// 从持久化数据库中获取区域信息
areaList = areaDao.queryArea();
try {
// 类型转换,将list转换为String(也就是json)
String jsonString = mapper.writeValueAsString(areaList);
// 将转换结果存储到redis数据对应的key中作缓存使用
jedisStrings.set(key, jsonString);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
} else { //如果redis数据库中已经缓存了相关信息,则直接获取,然后进行转换
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();
}
}
return areaList;
}
junit测试
首先需要让baseTest中加入扫描spring-redis.xml的配置
@ContextConfiguration({"classpath:spring/spring-dao.xml","classpath:spring/spring-service.xml","classpath:spring/spring-redis.xml"})
之前的测试,我们并不能测出是否使用了redis数据库,我们需要以debug的模式来调试,就是debug两次,先在getAreaList方法中设置断点,按f8直接跳到方法里,然后查看。