前面有一篇文章介绍了在 windows 系统里面搭建一个 Redis 环境,环境我们都搭建好了,总不至于搭着玩玩吧,接下来就会介绍,怎么样在最基础的单机形式下使用 Redis(循序渐进嘛,毕竟还有主从、哨兵和集群的形式,一下子也说不完)
引入 Redis 的依赖
在 pom.xml 文件中加入 Redis 的依赖
截图标注部分
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
配置 Redis 服务
在 application.properties 中为我们的工程配置 Redis 服务,这样在我们的工程启动以后,就会自动连接上 Redis 服务
截图部分如下
#Redis
spring.redis.host=127.0.0.1
# Redis服务器连接端口
spring.redis.port=6379
# 连接超时时间(毫秒),时间太短可能会连接超时
spring.redis.timeout=500
## Redis服务器连接密码(默认为空)
spring.redis.password=111111
## 连接池中的最大连接数
spring.redis.poolMaxTotal=10
## 连接池中的最大空闲连接
spring.redis.poolMaxIdle=10
## 连接池最大阻塞等待时间(使用负值表示没有限制)
spring.redis.poolMaxWait=3
设置 Redis 中的 value 的序列化方式
示例代码使用的是 fastjson 做的序列化,也可使用 Jackson,方式稍微有点区别
@Configuration
public class RedisConfig extends CachingConfigurerSupport {
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(factory);
// 设置 Redis 中 key 和 value 的序列化方式 (fastjson)
FastJsonRedisSerializer fastJsonRedisSerializer = new FastJsonRedisSerializer(Object.class);
template.setHashValueSerializer(fastJsonRedisSerializer);
template.setValueSerializer(fastJsonRedisSerializer);
template.setHashKeySerializer(new StringRedisSerializer());
template.setKeySerializer(new StringRedisSerializer());
return template;
}
}
测试 Redis 内存的存取
上述工作准备完成后,就差不多可以使用了,接下来就是来一段测试代码
为了看起来整齐,对原来的 RedisTemplate 做了一层封装
@Component
public class RedisUtils {
@Autowired
private RedisTemplate<String, Object> redisTemplate;
public RedisUtils(RedisTemplate<String, Object> redisTemplate) {
this.redisTemplate = redisTemplate;
}
//----------------- object ------------------
public boolean expire(String key, long expireTime) {
if (expireTime <= 0) {
return false;
}
try {
return redisTemplate.expire(key, expireTime, TimeUnit.SECONDS);
} catch (Exception e) {
return false;
}
}
public long getExpire(String key) {
return redisTemplate.getExpire(key);
}
public boolean hasKey(String key) {
try {
return redisTemplate.hasKey(key);
} catch (Exception e) {
return false;
}
}
public void delKey(String... key) {
if (key != null && key.length > 0) {
if (key.length == 1) {
redisTemplate.delete(key[0]);
} else {
redisTemplate.delete(Arrays.asList(key));
}
}
}
public Object get(String key) {
if (StringUtil.isEmpty(key)) {
return null;
}
return redisTemplate.opsForValue().get(key);
}
public boolean set(String key, Object obj) {
if (StringUtil.isEmpty(key)) {
return false;
}
try {
redisTemplate.opsForValue().set(key, obj);
return true;
} catch (Exception e) {
return false;
}
}
public boolean set(String key, Object obj, long expire) {
if (StringUtil.isEmpty(key)) {
return false;
}
try {
redisTemplate.opsForValue().set(key, obj, expire, TimeUnit.SECONDS);
return true;
} catch (Exception e) {
return false;
}
}
}
再来看看调用处的代码逻辑,里面的逻辑很简单
@RestController
@RequestMapping(Constant.URL.USER)
@Slf4j
public class UserController extends BaseController{
@Autowired
private RedisUtils redisUtils;
@Autowired
private UserServiceImp userService;
@Autowired
private RoleService roleService;
@PostMapping("/new")
public Response addUserInfo(@RequestBody UserInfo user) {
log.debug("addUserInfo" + JSON.toJSONString(user));
Response ret = new Response();
ret.setSuccess(ErrorCode.ERR_UNKNOW);
if (user == null) {
ret.setSuccess(ErrorCode.ERR_USER_INFO);
return ret;
}
Role roleTag = new Role();
roleTag.setId(user.getRole());
List<Role> testSet = roleService.getRoles(roleTag);
if (testSet == null || testSet.size() == 0) {
ret.setSuccess(ErrorCode.ERR_ROLE_NOT_EXIST);
return ret;
}
if (user.getId() != null) {
user.setId(null);
}
try {
UserInfo toRet = userService.addUserInfo(user);
toRet.setUserPwd(Constant.PWD_2_SHOW);
if (toRet != null) {
boolean testFlag = redisUtils.set(Constant.URL.USER + toRet.getId(), toRet);
System.out.println("testFlag " + testFlag);
ret.setSuccess(ErrorCode.SUCCESS);
ret.setContent(toRet);
return ret;
}
} catch (Exception e) {
e.printStackTrace();
ret.setSuccess(ErrorCode.ERR_USER_DUPLICATE);
}
return ret;
}
@RequestMapping(value = "/info/{id}", method = RequestMethod.GET)
public Response getUserInfo(@PathVariable("id") Integer id) {
// for(int i = 0; i < 2; i++) {
// hoshMQSender.send("不知道是什么鬼的测试内容" + i);
// }
Object test = redisUtils.get(Constant.URL.USER + id);
System.out.printf("getUserInfo " + JSON.toJSONString(test));
log.debug("getUserInfo {}", id);
UserInfo toRet = userService.getUserInfoById(id);
toRet.setUserPwd(Constant.PWD_2_SHOW);
Response ret = new Response();
ret.setSuccess(ErrorCode.SUCCESS);
ret.setContent(toRet);
return ret;
}
}
把程序跑起来,可以得到下面的测试结果
总结
测试代码的测试逻辑是,先插入一条数据,插入数据成功后,将插入的数据使用 Redis 存起来,查询的时候,先去 Redis 里面查询,再去 MySql 查询。这样的搭配比较符合一般的使用逻辑,Redis 的数据是存在内存中,查询速度比存在 IO 操作的 MySql 快;所以, Redis 用于存储热数据,主要指经常被使用的数据,从而,避免瞬时的高并发请求,使得数据库扛不住;MySql 则是存储全部的数据,两者相互协作