一、详情介绍
这里是使用Window版本的Redis,将下载好的Windows版本的Redis压缩包解压到一个目录下,客户端使用的是Redis Desktop Manager,使用Redis需要启动相应的服务,操作如下图所示
备注:双击打开方框中的服务会弹出redis-server窗口,redis-server的窗口不要关闭,关闭redis-server的窗口,则表示终止redis的服务。
SSM整合的文件及其他的配置文件和pom.xml文件的jar包,
将上述链接的配置文件复制过来时,需要修改database.propertise文件中数据库的名称
二、数据库文件
CREATE DATABASE /*!32312 IF NOT EXISTS*/`tour` /*!40100 DEFAULT CHARACTER SET utf8 */;
USE `tour`;
DROP TABLE IF EXISTS `category`;
CREATE TABLE `category` (
`id` int(4) NOT NULL AUTO_INCREMENT COMMENT '分类编号',
`categoryName` varchar(20) DEFAULT NULL COMMENT '分类名称',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8;
insert into `category`(`id`,`categoryName`) values (1,'博客'),(2,'课程'),(3,'开发者商城'),(4,'问答'),(5,'社区'),(6,'插件'),(7,'认证');
三、SSM项目中的pom文件导入spring-data-redis和jedis依赖的jar包(pom.xml)
<!-- 依赖管理 -->
<dependencies>
<!-- spring-data-redis依赖 -->
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
<version>2.1.8.RELEASE</version>
</dependency>
<!-- jedis -->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.10.2</version>
</dependency>
</dependencies>
四、redis的基本配置(redis.properties)
redis.host=127.0.0.1
redis.port=6379
redis.maxIdle=300
redis.maxWaitMillis=3000
redis.maxTotal=600
redis.testOnBorrow=false
redis.testOnReturn=true
五、spring整合redis的配置文件(spring-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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- 配置整合redis过程 -->
<!-- 1.配置数据库相关参数properties的属性:${url} -->
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:properties/redis.properties</value>
</list>
</property>
<property name="ignoreUnresolvablePlaceholders" value="true"/>
</bean>
<!-- 2.配置数据连接池 -->
<bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig">
<!--最大连接数-->
<property name="maxTotal" value="${redis.maxTotal}"/>
<!--最大空闲数-->
<property name="maxIdle" value="${redis.maxIdle}"/>
<!--连接时的最大等待毫秒数-->
<property name="maxWaitMillis" value="${redis.maxWaitMillis}"/>
<!--在提取一个jedis实例时,是否提前进行验证操作;如果为true,则得到的jedis实例均是
可用的-->
<property name="testOnBorrow" value="${redis.testOnBorrow}"/>
</bean>
<!-- 3.连接redis工厂 -->
<bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"
p:host-name="${redis.host}" p:port="${redis.port}" p:pool-config-ref="poolConfig"/>
<!-- 4.配置redisTemplate对象 -->
<bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
<property name="connectionFactory" ref="jedisConnectionFactory"/>
<property name="keySerializer">
<bean class="org.springframework.data.redis.serializer.StringRedisSerializer"/>
</property>
<property name="valueSerializer">
<bean class="org.springframework.data.redis.serializer.StringRedisSerializer"/>
</property>
</bean>
</beans>
六、spring-dao.xml文件中引入spring-redis.xml(spring-dao.xml)
<!-- 导入sping-redis.xml文件 -->
<import resource="classpath:spring/spring-redis.xml"/>
七、Category实体类
package entity;
import java.io.Serializable;
/**
* 分类表
*/
public class Category implements Serializable {
private Integer id; /*分类编号*/
private String categoryName; /*分类名称*/
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getCategoryName() {
return categoryName;
}
public void setCategoryName(String categoryName) {
this.categoryName = categoryName;
}
public Category() { }
public Category(Integer id, String categoryName) {
this.id = id;
this.categoryName = categoryName;
}
@Override
public String toString() {
return "Category{" +
"id=" + id +
", categoryName='" + categoryName + '\'' +
'}';
}
}
八、工具类:json字符串转换类
package tools;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
/**
* json字符串转换类
*/
public class ObjectMapperTools {
/**
* 创建ObjectMapper对象
*/
private static ObjectMapper objectMapper = null;
/*在静态代码块下,objectMapper只会创建一次*/
static {
objectMapper = new ObjectMapper();
/*如果是空对象的时候,不抛异常(如果使用了mybatis懒加载必须设置)*/
objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS,false);
}
/**
* 获取ObjectMapper对象
* @return ObjectMapper对象
*/
public static ObjectMapper getObjectMapper(){
return objectMapper;
}
}
九、数据访问层CategoryDao接口
package dao;
import entity.Category;
import org.apache.ibatis.annotations.Select;
import org.springframework.stereotype.Repository;
import java.util.List;
/**
* 数据访问层CategoryDao接口
*/
@Repository
public interface CategoryDao {
/**
* 获取分类的信息
* @return 分类的信息
*/
@Select("SELECT * FROM `category` ORDER BY id")
List<Category> getCategoryList();
}
十、业务逻辑层CategoryService接口
package service;
/**
* 业务逻辑层CategoryService接口
*/
public interface CategoryService {
/**
* 获取存在Redis中的数据
* @return Redis中的数据
*/
String findCategoryList() throws Exception;
}
十一、业务逻辑层CategoryServiceImpl实现类
package service.impl;
import dao.CategoryDao;
import entity.Category;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import service.CategoryService;
import tools.ObjectMapperTools;
import java.util.List;
/**
* 业务逻辑层CategoryServiceImpl实现类
*/
@Service
public class CategoryServiceImpl implements CategoryService {
@Autowired
private CategoryDao categoryDao;
@Autowired
private RedisTemplate redisTemplate;
@Override
public String findCategoryList() throws Exception {
/*获取json数据*/
String jsonData = (String) redisTemplate.opsForValue().get("categoryList");
/*判断是否从redis中获取到数据*/
if (jsonData == null) {
/*若Redis中存储的数据过时,json数据无效时,则去数据库获取List<Category>的数据*/
List<Category> categoryList = categoryDao.getCategoryList();
/*将List<Category>中的数据转换成json字符串*/
jsonData = ObjectMapperTools.getObjectMapper().writeValueAsString(categoryList);
/*将categoryList中的数据写入Redis中*/
redisTemplate.opsForValue().set("categoryList", jsonData);
}
/*返回json数据*/
return jsonData;
}
}
十二、表现层CategoryController类
package web;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import service.CategoryService;
/**
* 表现层CategoryController类
*/
@Controller
@RequestMapping("/category")
public class CategoryController {
@Autowired
private CategoryService categoryService;
/**
* 获取分类类别的json数据
* @return json数据
* @throws Exception 异常
*/
@ResponseBody
@RequestMapping(value = "/categoryList", method = RequestMethod.GET)
public String getCategoryList() throws Exception {
/*获取分类类别的json数据*/
String jsonData = categoryService.findCategoryList();
/*将json数据响应给前端页面*/
return jsonData;
}
}
十三、页面展现数据
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ page contentType="text/html;charset=UTF-8" language="java"%>
<c:set var="url" value="${pageContext.request.contextPath}"/>
<!DOCTYPE html>
<!-- 网页使用的语言 -->
<html lang="zh-CN">
<head>
<!-- 指定字符集 -->
<meta charset="utf-8">
<!-- 使用Edge最新的浏览器的渲染方式 -->
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<!-- viewport视口:网页可以根据设置的宽度自动进行适配,在浏览器的内部虚拟一个容器,容器的宽度与设备的宽度相同。
width: 默认宽度与设备的宽度相同
initial-scale: 初始的缩放比,为1:1 -->
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- 上述3个meta标签*必须*放在最前面,任何其他内容都*必须*跟随其后! -->
<title>分类列表</title>
<!-- 1. 导入CSS的全局样式 -->
<link href="statics/css/bootstrap.min.css" rel="stylesheet">
<!--导入jquery-->
<script src="statics/js/jquery-3.3.1.min.js"></script>
<!-- 3. 导入bootstrap的js文件 -->
<script src="statics/js/bootstrap.min.js"></script>
<style type="text/css">
.navitem {
width: 100%;
height: 40px;
background: #ffffff;
}
.nav {
width: 1200px;
margin: 20px auto 0;
}
.nav .picture {
margin-top:5px;
}
.nav li {
float: left;
margin-left: 60px;
}
.nav li a {
color: #3d3d3f;
font-size: 16px;
font-weight: bolder;
display: inline-block;
}
.nav>li>a:focus, .nav>li>a:hover{
background: none;
}
.nav>li>a {
padding: 10px 15px;
}
</style>
<script type="text/javascript">
$(function () {
/*显示分类导航列表*/
$.ajax({
url:"${url}/category/categoryList",
type:"GET",
data:{action:"getCategoryList"},
dataType:"json",
success:function(data) {
/*拼接html代码*/
var appendHtml = '';
/*拼接固定的html代码*/
appendHtml += '<li class="picture"><img src="statics/images/csdn.png"></li>';
/*循环拼接动态分类列表*/
$(data).each(function (i, category) {
/*获取分类编号*/
var categoryId = category.id;
/*获取分类名称*/
var categoryName = category.categoryName;
/*拼接html代码*/
appendHtml += '<li><a href="index.jsp?categoryId=' + categoryId + '">' + categoryName + '</a></li>';
});
/*拼接开源的html代码*/
appendHtml += '<li><a href="index.jsp">开源</a></li>';
/*将拼接的html代码存入.nav中*/
$(".nav").html(appendHtml);
}, error:function () {
alert("服务器繁忙!");
}
});
});
</script>
</head>
<body>
<div class="navitem">
<ul class="nav">
<!--
<li class="picture"><img src="statics/images/csdn.png"></li>
<li><a href="index.jsp">博客</a></li>
<li><a href="index.jsp">课程</a></li>
<li><a href="index.jsp">开发者商城</a></li>
<li><a href="index.jsp">问答</a></li>
<li><a href="index.jsp">社区</a></li>
<li><a href="index.jsp">插件</a></li>
<li><a href="index.jsp">认证</a></li>
-->
</ul>
</div>
</body>
</html>
十四、Redis客户端查看保存的数据
十五、页面展示的效果图