Spring Boot + MyBatis + Redis整合小案例
Redis 缓存
一、介绍
Redis缓存是一个高性能的key-value数据库,在大流量场景下,需要将一些经常展现和不会频繁变更的数据,存放在存取速率更快的地方,在技术选型中,常使用Redis作为缓存数据库。
应用场景:例如常见的电商场景,根据商品ID获取商品信息,这是就可以把店铺信息和商品详细信息写入redis,减少了去数据库查询的次数。
二、更新缓存的策略
更新缓存的四种策略:Cache aside, Read through, Write through, Write behind caching。具体参考 酷 壳 – CoolShell:https://coolshell.cn/articles/17416.html
其中Cache Aside Pattern是最常用的一种模式了。这也是这个小案例所使用的方式。
三、Redis的安装
windows版本下载地址:https://github.com/MicrosoftArchive/redis/releases
将文件解压,打开cmd窗口,运行cd切换到解压目录下,运行命令:redis-server.exe redis.windows.conf
注意:这个窗口不能关闭,否则就不能访问服务端了。
测试:
另开一个cmd窗口,切换到redis目录下,运行:redis-cli.exe
设置key-Value
四、简单案例
1.构建Spring Boot项目
这个可以参考网上的教程,此处不多说。可以进入http://start.spring.io进行项目的快速构建。
2.数据库设计
创建city表
DROP TABLE IF EXISTS city;
CREATE TABLE city (
id int(10) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '城市编号',
province_id int(10) UNSIGNED NOT NULL COMMENT '省份编号', -- UNSIGNED是无符号int,表示都为整数
city_name VARCHAR(25) DEFAULT NULL COMMENT '城市名称',
description VARCHAR(25) DEFAULT null COMMENT '描述',
PRIMARY KEY (id)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
insert into city VALUES(1,1,'南京市','六朝古都');
3.配置文件
需要在Spring Boot的配置文件中配置数据源,Redis,MyBatis等相关配置
# 数据源配置
spring.datasource.url=jdbc:mysql://localhost:3306/springbootdb?useUnicode=true&characterEncoding=utf8
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.username=root
spring.datasource.password=root
# MyBatis配置
mybatis.type-aliases-package=cn.hzr0523.entity
mybatis.mapper-locations=classpath:mapper/*.xml
# Redis配置
## Redis数据库索引(默认为0)
spring.redis.database=0
## Redis服务器地址
spring.redis.host=127.0.0.1
## Redis服务器连接端口
spring.redis.port=6379
## Redis服务器连接密码(默认为空)
spring.redis.password=
## 连接池最大连接数(使用负值表示没有限制)
spring.redis.pool.max-active=8
## 连接池最大阻塞等待时间(使用负值表示没有限制)
spring.redis.pool.max-wait=-1
## 连接池最大空闲连接
spring.redis.pool.max-idle=8
## 连接池最小空闲连接
spring.redis.pool.min-idle=0
## 连接超时时间(毫秒)
spring.redis.timeout=0
4.代码
Controller
@RestController
public class CityController {
@Autowired
private ICityService cityService;
@RequestMapping(value = "/api/city", method = RequestMethod.POST)
public Long saveCity(@RequestBody City city) {
return cityService.saveCity(city);
}
@RequestMapping(value = "/api/city/{id}", method = RequestMethod.GET)
public City findOneCity(@PathVariable("id") Long id){
return cityService.findCityById(id);
}
@RequestMapping(value = "/api/city", method = RequestMethod.PUT)
public Long updateCity(@RequestBody City city) {
return cityService.updateCity(city);
}
@RequestMapping(value = "/api/city/{id}", method = RequestMethod.DELETE)
public Long deleteCity(@PathVariable("id") Long id) {
return cityService.deleteCity(id);
}
}
Service
/**
* hezhi
* 2018/3/2 15:36
*/
@Service
public class CityServiceImpl implements ICityService {
private static final Logger LOGGER = LoggerFactory.getLogger(CityServiceImpl.class);
@Autowired(required = false)
private CityDao cityDao;
@Resource
private RedisTemplate redisTemplate;
public List<City> findAllCity() {
return null;
}
/**
* 获取城市逻辑:
* 如果缓存存在,获取缓存中的城市信息
* 如果缓存不存在,从DB中获取城市信息,然后插入缓存
* @param id
* @return
*/
public City findCityById(Long id) {
String key = "city_" + id ;
ValueOperations<String, City> operations = redisTemplate.opsForValue();
//缓存存在
boolean hasKey = redisTemplate.hasKey(key);
if(hasKey) {
City city = operations.get(key);
LOGGER.info("CityServiceImpl.findCityById:从缓存中获取了城市 >> " + city.toString());
return city;
}
//从DB中获取城市信息
City city = cityDao.findCityById(id);
//插入缓存
operations.set(key,city,10, TimeUnit.SECONDS);
LOGGER.info("CityServiceImpl.findCityById:从数据库中获取了城市 >> " + city.toString());
return city;
}
@Override
public Long saveCity(City city) {
return cityDao.saveCity(city);
}
@Override
public Long updateCity(City city) {
Long ret = cityDao.updateCity(city);
//如果缓存存在,删除缓存
String key = "city_" + city.getId();
boolean haskey = redisTemplate.hasKey(key);
if(haskey) {
redisTemplate.delete(key);
LOGGER.info("CityServiceImpl.updateCity:从缓存中删除了城市 >>" + city.toString());
}
return ret;
}
@Override
public Long deleteCity(Long id) {
Long ret = cityDao.deleteCity(id);
//如果缓存存在,删除缓存
String key = "city_" + id;
boolean haskey = redisTemplate.hasKey(key);
if(haskey) {
redisTemplate.delete(key);
LOGGER.info("CityServiceImpl.updateCity:从缓存中删除了城市ID >>" + id);
}
return ret;
}
}
mappe.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="cn.hzr0523.dao.CityDao">
<resultMap id="BaseResultMap" type="cn.hzr0523.entity.City">
<result column="id" property="id" />
<result column="province_id" property="provinceId" />
<result column="city_name" property="cityName" />
<result column="description" property="description" />
</resultMap>
<parameterMap id="City" type="cn.hzr0523.entity.City"/>
<sql id="Base_Column_List">
id, province_id, city_name, description
</sql>
<select id="findCityById" resultMap="BaseResultMap" parameterType="java.lang.Long">
select
<include refid="Base_Column_List" />
from city
where id = #{id}
</select>
<select id="findAllCity" resultMap="BaseResultMap" >
select
<include refid="Base_Column_List" />
from city
</select>
<insert id="saveCity" parameterMap="City" useGeneratedKeys="true" keyProperty="id">
insert into
city(id,province_id,city_name,description)
values
(#{id},#{provinceId},#{cityName},#{description})
</insert>
<update id="updateCity" parameterMap="City">
update
city
set
<if test="provinceId!=null">
province_id = #{provinceId},
</if>
<if test="cityName!=null">
city_name = #{cityName},
</if>
<if test="description!=null">
description = #{description}
</if>
where
id = #{id}
</update>
<delete id="deleteCity" parameterType="java.lang.Long">
delete from
city
where
id = #{id}
</delete>
</mapper>
上一篇: Sql优化-2 索引
推荐阅读
-
Spring boot Mybatis整合构建Rest服务(超细版)
-
Spring Boot(十三):整合Redis哨兵,集群模式实践
-
spring boot mybatis 整合教程
-
HBase 系列(十一)—— Spring/Spring Boot + Mybatis + Phoenix 整合
-
Spring Boot 整合 MyBatis 连接 Oracle数据库
-
Spring Boot整合mybatis(一)实例代码
-
spring Boot与Mybatis整合优化详解
-
spring boot整合mybatis利用Mysql实现主键UUID的方法
-
IDEA Spring Boot整合Mybatis-Plus
-
Spring boot整合Mybatis-plus分页插件的使用