spring boot整合mybatis+mysql
一添加jar包
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency>
二在application.properties文件中添加redis连接配置信息
#redis配置 spring.redis.database=0 spring.redis.host=localhost spring.redis.port=6379 spring.redis.client-name= spring.redis.password= spring.redis.lettuce.pool.max-active=8 spring.redis.lettuce.pool.max-wait=1 spring.redis.lettuce.pool.max-idle=8 spring.redis.lettuce.pool.min-idle=0
三 实体类实现序列化接口
package cn.lgy.springboot.redis.domain; import java.io.Serializable; /** * @author liyang * @date 2020/8/16 12:58 * @description: */ public class User implements Serializable { private Integer id; private String email; private String nickName; private String passWord; private String regTime; private String userName;
四 在serviceImpl中将进行逻辑判断
package cn.lgy.springboot.redis.service.impl; import cn.lgy.springboot.redis.domain.User; import cn.lgy.springboot.redis.mapper.UserMapper; import cn.lgy.springboot.redis.service.UserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.serializer.RedisSerializer; import org.springframework.data.redis.serializer.StringRedisSerializer; import org.springframework.stereotype.Service; import java.util.List; /** * @author liyang * @date 2020/8/16 13:21 * @description: */ @Service public class UserServiceImpl implements UserService { @Autowired UserMapper userMapper; /** * 将RedisTemplate模板引擎注入到spring boot容器中 */ @Autowired RedisTemplate<String, Object> redisTemplate; @Override public List<User> allUsers () { //设置redis的key键反序列化使其在redis数据库中变为可读 RedisSerializer redisSerializer = new StringRedisSerializer(); redisTemplate.setKeySerializer(redisSerializer); //根据key获取redis数据库中的值,如果有值就从缓存中取出,没有就查询数据库 List<User> users = (List<User>)redisTemplate.opsForValue().get("user"); //判断redis数据库中是否有该数据 if (users==null){ //没有该数据就查询数据库 users = userMapper.selectAllUsers(); //将查询出来的数据添加到redis数据库中 redisTemplate.opsForValue().set("user", users); } return users; } }
适用于访问量比较大,高并发情况. 容易发生缓存穿透的问题,可能有10000个人同时执行查询操作,上面的逻辑会造成10000个人同时查询,当redis中没有缓存时会进行10000次查询数据库并将缓存放入数据库中.但我们只需要一个人查询,其他9999人查询缓存.
解决方案一:
在service实现类的方法上添加synchromnized 但是会牺牲性能
@Override public synchronized List<User> allUsers () { //设置redis的key键反序列化使其在redis数据库中变为可读 RedisSerializer redisSerializer = new StringRedisSerializer(); redisTemplate.setKeySerializer(redisSerializer); //根据key获取redis数据库中的值,如果有值就从缓存中取出,没有就查询数据库 List<User> users = (List<User>)redisTemplate.opsForValue().get("user"); //判断redis数据库中是否有该数据 if (users==null){ //没有该数据就查询数据库 users = userMapper.selectAllUsers(); //将查询出来的数据添加到redis数据库中 redisTemplate.opsForValue().set("user", users); } return users; }
解决方式二:
在方法内部的逻辑前synchronized 该方式会提高一点性能,比上面的好,但也会影响性能
@Override
public List<User> allUsers () {
//设置redis的key键反序列化使其在redis数据库中变为可读
RedisSerializer redisSerializer = new StringRedisSerializer();
redisTemplate.setKeySerializer(redisSerializer);
//根据key获取redis数据库中的值,如果有值就从缓存中取出,没有就查询数据库
List<User> users = (List<User>)redisTemplate.opsForValue().get("user");
//判断redis数据库中是否有该数据
if (users==null) {
synchronized (this) {
users = (List<User>) redisTemplate.opsForValue().get("user");
if (users == null) {
//没有该数据就查询数据库
users = userMapper.selectAllUsers();
//将查询出来的数据添加到redis数据库中
redisTemplate.opsForValue().set("user", users);
}
}
}
return users;
}
哨兵模式 Redis集群配置
application.properties
#redis配置哨兵集群模式
#默认名称就是mymaster
spring.redis.sentinel.master=mymaster
#配置多个哨兵的IP和端口
spring.redis.sentinel.nodes=192.168..106.128:26380,192.168.128:26382,192.168.128:26384,
#配置redis密码:
spring.redis.password=123456
程序逻辑不用动,使用高并发环境的逻辑处理