1 环境搭建
在实际开发中,我们使用Redis,一般是使用RedisTemplate类来操作Redis,这种方式比较灵活,在Redis各种使用场景下都可以使用.
第一步: 导入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>
Spring boot使用spring-boot-starter-data-redis来自动配置Lettuce和Jedis这两种redis的Java客户端。默认选用的是Lettuce。
默认使用Lettuce,改用Jedis:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<exclusions>
<exclusion>
<groupId>io.lettuce</groupId>
<artifactId>lettuce-core</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>
第二步: 添加redis配置
#lettuce的配置:
spring:
redis:
# Redis数据库索引(默认为0
database: 0
# Redis服务器地址 默认 127.0.0.1
host: 192.168.145.138
# Redis服务器连接端口 默认6379
port: 6379
# Redis服务器连接密码(默认为空)
password: 123
lettuce:
pool:
# 连接池中的最大空闲连接 默认 8
max-idle: 10
# 连接池中的最小空闲连接 默认 0
min-idle: 3
# 连接池最大连接数(使用负值表示没有限制) 默认值8
max-active: 20
# 连接池最大阻塞等待时间(使用负值表示没有限制) 默认值-1
max-wait: -1ms
# 连接超时时间(毫秒)
timeout: 10000ms
如果是jedis配置,只需要把lettice修改为jedis即可:
spring:
redis:
database: 0
host: 192.168.145.138
port: 6379
password: 123
jedis:
pool:
min-idle: 3
max-active: 20
max-wait: -1ms
max-idle: 10
# 连接超时时间(毫秒)
timeout: 10000ms
spring: redis: database: 0 host: 192.168.145.138 port: 6379 password: 123 jedis: pool: min-idle: 3 max-active: 20 max-wait: -1ms max-idle: 10 # 连接超时时间(毫秒) timeout: 10000ms
lettcus与jedis区别:
1. jedis连接Redis服务器是直连模式,当多线程模式下使用jedis会存在线程安全问题,解决方案可以通过配置连接池使每个连接专用,这样整体性能就大受影响。 2. lettcus基于Netty框架进行与Redis服务器连接,底层设计中采用StatefulRedisConnection。 StatefulRedisConnection自身是线程安全的,可以保障并发访问安全问题,所以一个连接可以被多线程复用。当然lettcus也支持多连接实例一起工作。 Spring Boot会根据application.yml的配置,自动生成两个bean: RedisTemplate<Object,Object>和StringRedisTemplate。2 使用RedisTemplate来操作Redis
Spring封装了RedisTemplate/StringRedisTemplate对象来进行对Redis的各种操作,它支持所有的Redis原生的api.RedisTemplate/StringRedisTemplate位于Spring-data-redis包下.
RedisTemplate/StringRedisTemplate中定义了对redis的5种数据结构的操作:
opsForValue() 操作字符串
opsForHash() 操作hash
opsForList() 操作list
opsForSet() 操作set
opsForZSet() 操作ZSet
注意:
RedisTemplate与StringRedisTemplate之间不能混用,他们是有区别的.
两者数据各自存,各自取,数据不互通。
RedisTemplate不能取StringRedisTemplate存入的数据。
StringRedisTemplate不能取RedisTemplate存入的数据
2.序列化策略不同。
RedisTemplate默认采用JDK的序列化策略
StringRedisTemplate默认采用String的序列化策略
如果你需要缓存的是字符串,那么你就使用
StringRedisTemplate
即可。但是如果你的数据是复杂的对象类型,而取出的时候又不想做任何的数据转换,直接从Redis里面取出一个对象,那么使用RedisTemplate是更好的选择@Service public class UserServiceImpl implements UserService { @Autowired private UserMapper userMapper; @Autowired private RedisTemplate redisTemplate; @Override //事务控制 @Transactional(propagation = Propagation.SUPPORTS,readOnly = true) public Page<User> queryByPage(Integer current, Integer size, UserVO userVO) { Page<User> page = new Page<>(current,size); //排序 根据年龄升序排序 List<OrderItem> orderItems = new ArrayList<>(); orderItems.add(OrderItem.asc("age")); page.setOrders(orderItems); StringBuffer redisKey = new StringBuffer("page_"); redisKey.append(current); //设置条件 QueryWrapper<User> queryWrapper = new QueryWrapper<>(); if(userVO != null){ if(!StringUtils.isEmpty(userVO.getName())){ queryWrapper.like("name",userVO.getName()); redisKey.append("_name_"+userVO.getName()); } if(!StringUtils.isEmpty(userVO.getGender())){ queryWrapper.eq("gender",userVO.getGender()); redisKey.append("_gender_"+userVO.getGender()); } if(Objects.nonNull(userVO.getStartAge())){ queryWrapper.gt("age",userVO.getStartAge()); redisKey.append("_age1_"+userVO.getStartAge()); } if(Objects.nonNull(userVO.getEndAge())){ queryWrapper.lt("age",userVO.getEndAge()); redisKey.append("_age2_"+userVO.getEndAge()); } } if(redisTemplate.hasKey(redisKey.toString())){ return (Page<User>)redisTemplate.opsForValue().get(redisKey.toString()); } userMapper.selectPage(page,queryWrapper); redisTemplate.opsForValue().set(redisKey.toString(),page,1,TimeUnit.MINUTES); return page; } }