知識點
1.Redis的應用場景?
1.Token令牌的生成
2.短信驗證碼的code
3.可以實現緩存查詢數據 a. 減輕我們的數據庫的訪問壓力 Redis與mysql數據庫不同步的問題
4.Redis幫助實現計數器
5.分佈式鎖
6.延遲操作 分佈式消息中間件
注意:Redis官方是沒有windows版本的,只有linux,這時候因爲 在nio中epoll只有linux操作系統獨有
2.Redis線程模型?
Redis的採用NIO的IO多路複用原則,也就是一個線程維護多個不同的Redis客戶端連接,從而提高處理
併發效率和保證線程安全問題.底層採用linux操作系統的epoll技術避免空輪詢.
3.Redis數據結構?
String類型、Hsh類型、List類型、Set類型 、Sorted-Sets
String: 存儲 set key value ; 獲取 get key
Hsh: 存儲 hmset key zhang 28 li 27 liu 23; 獲取 hget key zhang/li/liu
list: 存儲 lpush key xiaomi xiaojun xiaoqiang ;獲取 lrange key 0(開始位置) 3(結束)
移出第一個元素並獲得: lpop key
set: 存儲 sadd key xiao1 xiao2 xiao3 xiao3(不能重複,無序) 存儲3個元素
獲取 smembers key
sortset: 存儲 zadd key 1 zhang zadd key 2 li zadd key 3 zhang
(序號 值 ;有序的,值不能重複,重複存入,序號會覆蓋之前序號,取值按照序號排序)
獲取 zrange key 0 10 withscores(帶上此參數,取值包含序號)
4.SpringBoot整合redis使用注意事項:
1.使用對象必須序列化 implements Serializable
2. private RedisTemplate<String ,Object> redisTemplate;使用@Resource注入,
不能使用@Autowired,因爲按照類型找的autoWired找不到這種泛型類
demo地址:鏈接:https://pan.baidu.com/s/1PKxK4waUF0jfuofqx1Ajxw
提取碼:fsh3
Springboot整合redis 使用(實體類必須實現序列化)
1.pom.xml依賴
<!--SpringBoot整合redis-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--springboot整合 mybatis -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.2</version>
</dependency>
<!--mysql依賴-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.1.46.sec06</version>
</dependency>
2.application.properties配置文件
server.port=8080
spring.application.name=redis
spring.datasource.url=jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2B8
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.redis.host=127.0.0.1
spring.redis.password=zsq2170
spring.redis.port=6379
spring.redis.database=1
#連接池最大連接數(使用負值表示沒有限制)
spring.redis.lettuce.pool.max-active=8
# 連接池最大阻塞等待時間(使用負值表示沒有限制)
spring.redis.jedis.pool.max-wait=-1ms
# 連接池中的最大空閒連接
spring.redis.jedis.pool.max-idle=8
# 連接池中的最小空閒連接
spring.redis.jedis.pool.min-idle=0
# 連接超時時間(毫秒)
spring.redis.lettuce.shutdown-timeout=5000ms
3.編寫工具類 這裏redis存Json字符串工具類
@Component
public class RedisUtils {
@Autowired
private StringRedisTemplate redisTemplate;
//不設置超時時間
public void setString(String key ,String value){
setString(key,value,null);
}
//設置超時時間,單位秒
public void setString(String key ,String value ,Long timeOut){
if(null!=timeOut&&timeOut>0){
redisTemplate.opsForValue().set(key,value);
redisTemplate.expire(key,timeOut, TimeUnit.SECONDS);
}else {
redisTemplate.opsForValue().set(key,value);
}
}
public String getString(String key){
return redisTemplate.opsForValue().get(key);
}
}
4.這裏是redis存二進制工具類
@Component
public class RedisObjectUtils {
@Resource //此處不可使用@Autowired註解(會找不到redisTemplate) 實則redisTemplate已經初始化,且使用@Autowired會找不到此泛型類
private RedisTemplate<String ,Object> redisTemplate;
//不設置超時時間
public void setObject(String key ,Object value){
setObject(key,value,null);
}
//設置超時時間,單位秒
public void setObject(String key ,Object value ,Long timeOut){
if(null!=timeOut&&timeOut>0){
redisTemplate.opsForValue().set(key,value);
redisTemplate.expire(key,timeOut, TimeUnit.SECONDS);
}else {
redisTemplate.opsForValue().set(key,value);
}
}
public Object getObject(String key){
return redisTemplate.opsForValue().get(key);
}
}
5.編寫測試接口
@RestController
public class RedisController {
@Autowired
private RedisUtils redisUtils; //redis存字符串工具類
@Autowired
private RedisObjectUtils redisObjectUtils; //redis存二進制工具類
//存json字符串
@GetMapping("/addUser")
public String addUser(UserEntity userEntity){
String json = JSON.toJSONString(userEntity);
redisUtils.setString("userEntity",json,300L);
return "存儲成功";
}
@GetMapping("/getUser")
public UserEntity getUser(String key){
String s = redisUtils.getString(key);
return JSON.parseObject(s, UserEntity.class);
}
//存二進制
@GetMapping("/addUserBinary")
public String addUserBinary(UserEntity userEntity){
redisObjectUtils.setObject("userEntity",userEntity,300L);
return "存儲成功";
}
@GetMapping("/getUserBinary")
public UserEntity getUserBinary(String key){
return (UserEntity)redisObjectUtils.getObject(key);
}
}
6.調用接口測試.注意事項,實體對象一定要實現序列化
SpringBoot 整合Redis 註解形式
1.依賴和配置文件一樣 ,添加redis配置類信息
@Configuration
@EnableCaching
public class RedisCacheConfig extends CachingConfigurerSupport{
/**
* 配置自定義redisTemplate
*/
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(connectionFactory);
template.setValueSerializer(jackson2JsonRedisSerializer());
//使用StringRedisSerializer來序列化和反序列化redis的key值
template.setKeySerializer(new StringRedisSerializer());
template.setStringSerializer(new StringRedisSerializer());
template.setHashKeySerializer(new StringRedisSerializer());
template.setHashValueSerializer(jackson2JsonRedisSerializer());
template.afterPropertiesSet();
return template;
}
//json序列化
@Bean
public RedisSerializer<Object> jackson2JsonRedisSerializer() {
//使用Jackson2JsonRedisSerializer來序列化和反序列化redis的value值
Jackson2JsonRedisSerializer serializer = new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper mapper = new ObjectMapper();
mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
serializer.setObjectMapper(mapper);
return serializer;
}
/**
* 配置緩存管理器
*/
@Bean
public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {
// 生成一個默認配置,通過config對象即可對緩存進行自定義配置
RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig();
// 設置緩存的默認過期時間,也是使用Duration設置 單位分鐘
config = config.entryTtl(Duration.ofMinutes(10))
// 設置 key爲string序列化
.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()))
// 設置value爲json序列化
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer()))
// 不緩存空值
.disableCachingNullValues();
// 使用自定義的緩存配置初始化一個cacheManager
return RedisCacheManager
.builder(redisConnectionFactory)
.cacheDefaults(config)
.transactionAware()
.build();
}
/**
* 定製化key生成器
* 設置 全限定類名 + 方法名 + 參數名 共同組成 key
* @return key生成器
* @date 2019/4/12 14:09
*/
@Bean
@Override
public KeyGenerator keyGenerator() {
return (Object target, Method method, Object... params) -> {
StringBuilder sb = new StringBuilder(16);
sb.append(target.getClass().getName());
sb.append("_");
sb.append(method.getName());
sb.append("_");
for (int i = 0; i < params.length; i++) {
sb.append(params[i]);
if (i < params.length - 1) {
sb.append(",");
}
}
return sb.toString();
};
}
}
2.測試接口
@RestController
public class MemberController {
@Autowired
private MemberMapper memberMapper;
@Cacheable(cacheNames = "members" ,key = "'getListMember'")
@GetMapping("/getListMember")
public List<MemberEntity> getListMember(){
return memberMapper.fandAll();
}
/**
* Cacheable:可用於類或方法上;在目標方法執行前,會根據key先去緩存中查詢看是否有數據,有就直接
* 返回緩存中的key對應的value值。不再執行目標方法;無則執行目標方法,並將方法的返回值
* 作爲value,並以鍵值對的形式存入緩存
* condition: 緩存註解檢查緩存中是否有對應的key-value 在 運行目標方法之前,
*/
@Cacheable(cacheNames = "members" ,key = "'getMemberById'+#id" , condition = "#id !=null")
@GetMapping("/getMemberById1")
public MemberEntity getMemberById1(Long id){
return memberMapper.getMemberById(id);
}
/**
* CachePut:可用於類或方法上;在執行完目標方法後,並將方法的返回值作爲value,並以鍵值對的形式存入緩存中
*/
@CachePut(cacheNames = "members" ,key = "'getMemberById'+#id")
@GetMapping("/getMemberById2")
public MemberEntity getMemberById2(Long id){
return memberMapper.getMemberById(id);
}
/**
* CacheEvict:可用於類或方法上;在執行完目標方法後,清除緩存中對應key的數據(如果緩存
* 中有對應key的數據緩存的話)
* beforeInvocation:此屬性主要出現在@CacheEvict註解中, 默認false 表示先執行方法後結束後刪除緩存
* true->表示方法執行前生效,先刪除緩解再執行方法,不存在緩存沒被刪除情況
*/
@CacheEvict(cacheNames = "members" ,key = "'getMemberById'+#id" , beforeInvocation = true)
@GetMapping("/getMemberById3")
public MemberEntity getMemberById3(Long id){
return memberMapper.getMemberById(id);
}
/**
* 不指定key , 使用redisCacheConfig裏面的KeyGenerator生成策略 生成key
* unless : 功能是:是否令註解(在方法執行後的功能)不生效;若unless的結果爲true,則(方法執行後的功能)不生效;
* 若unless的結果爲false,則(方法執行後的)功能生效。
*/
@Cacheable(cacheNames = "KeyGenerator" , unless="#result == null")
@GetMapping("/getMemberById4")
public MemberEntity getMemberById4(Long id){
return memberMapper.getMemberById(id);
}
}