一、首页实现大广告
1、准备数据
2、在taotao-portal系统的资源配置文件中声明变量,并在springmvc.xml中读取资源文件
3、在taotao-portal项目中加入interface接口依赖,并在springmvc.xml配置文件中声明服务调用
4、修改index.jsp中加载大广告数据的代码
5、修改IndexController.java 代码
package com.taotao.portal.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import com.taotao.manager.service.ContentService;
@Controller
@RequestMapping("index")
public class IndexController {
@Value("${TAOTAO_AD_ID}")
private Long categoryId;
@Autowired
private ContentService contentService;
/**
* 访问系统首页
*/
@RequestMapping(method = RequestMethod.GET)
public String toIndex(Model model) {
//查询大广告数据
String AD = this.contentService.queryContentByCategoryId(this.categoryId);
model.addAttribute("AD", AD);
return "index";
}
}
6、编写Service层代码
ContentService.java
/**
* 根据内容分类ID获取大广告内容列表
* @param categoryId
* @return
*/
public String queryContentByCategoryId(Long categoryId);
ContentServicImpl.java
//声明转换json对象的MAPPER
private static final ObjectMapper MAPPER = new ObjectMapper();
/**
* 根据内容分类ID获取大广告内容列表
* @param categoryId
* @return
*/
public String queryContentByCategoryId(Long categoryId) {
//声明查询条件
Content param = new Content();
param.setCategoryId(categoryId);
//根据条件查询内容
List<Content> list = super.queryListByWhere(param);
//遍历结果,把数据按照前端页面需求,封装到List<Map<String, String>>中
//声明List容器
List<Map<String, Object>> resultList = new ArrayList<>();
//遍历返回的list集合
for (Content content : list) {
Map<String, Object> map = new HashMap<String, Object>();
//封装数据
map.put("srcB", content.getPic());
map.put("height", 240);
map.put("alt", "");
map.put("width", 670);
map.put("src", content.getPic2());
map.put("widthB", 550);
map.put("href", content.getUrl());
map.put("heightB", 240);
//把封装好的数据放到容器中
resultList.add(map);
}
//把封装好的list转换为json格式的数据
String json = "";
try {
json = MAPPER.writeValueAsString(resultList);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
//返回json数据
return json;
}
二、添加缓存分析
1、为什么要添加缓存?
随着访问用户越来越多,并发越来越大,直接从MySQL数据库查询性能较低。可以使用把数据进行缓存,从缓存读取速度更快。
2、什么样的数据需要添加缓存?
访问频率高
更新频率低
首页访问量很大,大广告的更新频率较低,所以可以添加缓存
可以使用redis增加缓存因为redis的读写速度快
我们的架构是把缓存放在服务层
服务层把需要缓存的数据放在redis中,
先从redis查询数据,如果redis没有数据,再去MySQL查询。
3、redis在项目架构中所处的位置
三、redis安装
1、单机版安装
http://blog.csdn.net/wingzhezhe/article/details/62044468
2、集群安装
http://blog.csdn.net/wingzhezhe/article/details/73323651
四、项目继承Redis
1、整合Redis分析
因为集群需要的服务器至少是6台,使用Redis集群的成本很高,所以如果没有业务要求,不会使用Redis集群。
而使用Redis集群的公司,为了节省成本,一般只会在生产环境使用集群,而开发环境使用Redis单机版,所以我们在整合项目的时候,需要单机版和集群版都要有。
我们可以创建一个接口,再编写单机版和集群版的实现类,使用spring进行管理,在部署时,使用哪种Redis,就切换那种实现类。
在taotao-manager-service创建com.taotao.manager.redis包进行管理
2、编写RedisUtils接口
package com.taotao.manager.redis;
/**
* 集成redis的接口
*
* @author Administrator
*
*/
public interface RedisUtils {
/**
* 保存数据
*
* @param key
* @param value
*/
public void set(String key, String value);
/**
* 保存数据,同时设置有效时间
*
* @param key
* @param value
* @param seconds
*/
public void set(String key, String value, Integer seconds);
/**
* 根据key查询数据
*
* @param key
* @return
*/
public String get(String key);
/**
* 根据key删除数据
*
* @param key
*/
public void delete(String key);
/**
* 根据key设置数据的有效时间
*
* @param key
* @param seconds
*/
public void expire(String key, Integer seconds);
/**
* 根据key,把value值加1并返回
*
* @param key
* @return
*/
public long incr(String key);
}
3、编写RedisUtils实现类
(1)、单机版RedisPool实现类
package com.taotao.manager.redis.impl;
import org.springframework.beans.factory.annotation.Autowired;
import com.taotao.manager.redis.RedisUtils;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
public class RedisPool implements RedisUtils {
@Autowired
private JedisPool jedisPool;
@Override
public void set(String key, String value) {
// 获取jedis连接对象
Jedis jedis = this.jedisPool.getResource();
// 使用连接对象操作redis
jedis.set(key, value);
// 关闭redis,归还连接给连接池
jedis.close();
}
@Override
public void set(String key, String value, Integer seconds) {
// 获取jedis连接对象
Jedis jedis = this.jedisPool.getResource();
// 使用连接对象操作redis
jedis.set(key, value);
jedis.expire(key, seconds);
// 关闭redis,归还连接给连接池
jedis.close();
}
@Override
public String get(String key) {
// 获取jedis连接对象
Jedis jedis = this.jedisPool.getResource();
// 使用连接对象操作redis
String result = jedis.get(key);
// 关闭redis,归还连接给连接池
jedis.close();
return result;
}
@Override
public void delete(String key) {
// 获取jedis连接对象
Jedis jedis = this.jedisPool.getResource();
// 使用连接对象操作redis
jedis.del(key);
// 关闭redis,归还连接给连接池
jedis.close();
}
@Override
public void expire(String key, Integer seconds) {
// 获取jedis连接对象
Jedis jedis = this.jedisPool.getResource();
// 使用连接对象操作redis
jedis.expire(key, seconds);
// 关闭redis,归还连接给连接池
jedis.close();
}
@Override
public long incr(String key) {
// 获取jedis连接对象
Jedis jedis = this.jedisPool.getResource();
// 使用连接对象操作redis
Long value = jedis.incr(key);
// 关闭redis,归还连接给连接池
jedis.close();
return value;
}
}
(2)、集群版RedisCluster实现类
package com.taotao.manager.redis.impl;
import org.springframework.beans.factory.annotation.Autowired;
import com.taotao.manager.redis.RedisUtils;
import redis.clients.jedis.JedisCluster;
public class RedisCluster implements RedisUtils {
@Autowired
private JedisCluster jedisCluster;
@Override
public void set(String key, String value) {
this.jedisCluster.set(key, value);
}
@Override
public void set(String key, String value, Integer seconds) {
this.jedisCluster.set(key, value);
this.jedisCluster.expire(key, seconds);
}
@Override
public String get(String key) {
String result = this.jedisCluster.get(key);
return result;
}
@Override
public void delete(String key) {
this.jedisCluster.del(key);
}
@Override
public void expire(String key, Integer seconds) {
this.jedisCluster.expire(key, seconds);
}
@Override
public long incr(String key) {
Long value = this.jedisCluster.incr(key);
return value;
}
}
4、添加redis.properties
(1)、添加redis.properteis资源文件
(2)、在spring配置文件中读取redis的资源文件
5、配置spring管理Redis
<?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:mvc="http://www.springframework.org/schema/mvc"
xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://code.alibabatech.com/schema/dubbo
http://code.alibabatech.com/schema/dubbo/dubbo.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 配置单机版的连接池 -->
<bean class="redis.clients.jedis.JedisPool">
<!-- 配置单机版端ip -->
<constructor-arg name="host" value="${redis.host}" />
<!-- 配置单机版端口号 -->
<constructor-arg name="port" value="${redis.port}" />
</bean>
<!-- 配置集群版的连接对象 -->
<bean class="redis.clients.jedis.JedisCluster">
<!-- 配置集群节点信息 -->
<constructor-arg name="nodes">
<set>
<bean class="redis.clients.jedis.HostAndPort">
<constructor-arg name="host" value="${redis.host1}" />
<constructor-arg name="port" value="${redis.port1}" />
</bean>
<bean class="redis.clients.jedis.HostAndPort">
<constructor-arg name="host" value="${redis.host2}" />
<constructor-arg name="port" value="${redis.port2}" />
</bean>
<bean class="redis.clients.jedis.HostAndPort">
<constructor-arg name="host" value="${redis.host3}" />
<constructor-arg name="port" value="${redis.port3}" />
</bean>
<bean class="redis.clients.jedis.HostAndPort">
<constructor-arg name="host" value="${redis.host4}" />
<constructor-arg name="port" value="${redis.port4}" />
</bean>
<bean class="redis.clients.jedis.HostAndPort">
<constructor-arg name="host" value="${redis.host5}" />
<constructor-arg name="port" value="${redis.port5}" />
</bean>
<bean class="redis.clients.jedis.HostAndPort">
<constructor-arg name="host" value="${redis.host6}" />
<constructor-arg name="port" value="${redis.port6}" />
</bean>
</set>
</constructor-arg>
</bean>
<!-- 配置单机版的实现类,目前将单机版注释,即表示使用的是集群,如果想使用单机版,只需要将集群注释,单机版放开即可进行切换 -->
<!-- <bean class="com.taotao.manager.redis.impl.RedisPool"></bean> -->
<!-- 配置集群版的实现类 -->
<bean class="com.taotao.manager.redis.impl.RedisCluster"></bean>
</beans>
五、首页大广告添加缓存
1、在redis资源文件中添加redis缓存大广告的key
2、改造内容实现类中根据分类id查询内容的方法
// 声明JedisUtils对象
@Autowired
private RedisUtils redisUtils;
@Value("${TAOTAO_PORTAL_REDISID}")
private String TAOTAO_PORTAL_REDISID;
/**
* 根据内容分类ID获取大广告内容列表
*
* @param categoryId
* @return
*/
public String queryContentByCategoryId(Long categoryId) {
try {
// 1.先从redis缓存中获取大广告数据
String redisJson = this.redisUtils.get(this.TAOTAO_PORTAL_REDISID);
// 判断是否从redis中获取到数据
if (StringUtils.isNoneBlank(redisJson)) {
return redisJson;
}
} catch (Exception e1) {
e1.printStackTrace();
}
// 2.如果没有从redis中获取数据,调用方法从数据库中查询数据
// 声明查询条件
Content param = new Content();
param.setCategoryId(categoryId);
// 根据条件查询内容
List<Content> list = super.queryListByWhere(param);
// 遍历结果,把数据按照前端页面需求,封装到List<Map<String, String>>中
// 声明List容器
List<Map<String, Object>> resultList = new ArrayList<>();
// 遍历返回的list集合
for (Content content : list) {
Map<String, Object> map = new HashMap<String, Object>();
// 封装数据
map.put("srcB", content.getPic());
map.put("height", 240);
map.put("alt", "");
map.put("width", 670);
map.put("src", content.getPic2());
map.put("widthB", 550);
map.put("href", content.getUrl());
map.put("heightB", 240);
// 把封装好的数据放到容器中
resultList.add(map);
}
// 把封装好的list转换为json格式的数据
String json = "";
try {
json = MAPPER.writeValueAsString(resultList);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
// 3.将新查询出来的大广告数据放入redis缓存中,并设置有效时间
this.redisUtils.set(this.TAOTAO_PORTAL_REDISID, json, 60 * 60 * 24);
// 返回json数据
return json;
}