專業(yè) 網(wǎng)站設(shè)計公司php開源建站系統(tǒng)
Redis
簡介
Redis是一個基于內(nèi)存的key-value結(jié)構(gòu)數(shù)據(jù)庫
- 基于內(nèi)存存儲,讀寫性能高
- 適合存儲熱點數(shù)據(jù)(熱點商品、資訊、新聞)
- 企業(yè)應(yīng)用廣泛
基礎(chǔ)操作
啟動
在redis安裝目錄中打開cmd,輸入如上圖指令即可啟動,按下crtl+c停止
連接
保證服務(wù)端啟動時,在cmd命令行中輸入redis-cli.exe -h 用戶名 -p 端口號 -a 密碼
數(shù)據(jù)類型
常用命令
字符串操作命令
- SET key value 設(shè)置指定key的值
- GET key 獲取指定key的值
- SETEX key seconds value 設(shè)置指定key的值,并將key的過期時間設(shè)為seconds秒
- SETNX key value 只有key不存在時設(shè)置key的值(key已存在則無法設(shè)置)
哈希操作命令(Hash Map)
Redis hash 是一個String類型的field和value的映射表,hash特別適合用于存儲對象,常用命令:
(這些命令中的key是哈希表名,field是字段名,value是值)
- HSET key field value 將哈希表key中的字段field的值設(shè)為value
- HGET key field value 獲取存儲在哈希表中的指定字段
- HDEL key field 刪除存儲在哈希表中的指定字段
- HKEYS key 獲取哈希表中所有字段
- HVALS key 獲取哈希表中所有值
列表操作命令(Linked List)
Redis列表是簡單的String列表,按照插入順序排序,常用命令:
- LPUSH key value1 [value2] 將一個或多個值插入到列表頭部
- LRANGE key start stop 獲取列表指定范圍內(nèi)的元素
- RPOP key 移除并獲取列表最后一個元素
- LLEN key 獲取列表長度
集合操作命令(Set)
Reids set 是String類型的無序集合。集合成員是唯一的,集合中不能出現(xiàn)重復(fù)的數(shù)據(jù),常用命令:
- SADD key member1 [member2] 向集合添加一個或多個成員
- SMEMBERS key 返回集合中的所有成員
- SCARD key 獲取集合的成員數(shù)
- SINTER key1 [key2] 返回給定所有集合的交集
- SUNION key1 [key2] 返回所有給定集合的并集
- SREM key member1 [member2] 刪除集合中一個或多個成員
有序集合操作命令
Redis有序集合是String類型元素的集合,且不允許有重復(fù)成員(集合中的元素是string類型,每個元素有一個double類型的分?jǐn)?shù),會自動根據(jù)分?jǐn)?shù)進(jìn)行排序)。每個元素都會關(guān)聯(lián)一個double類型的分?jǐn)?shù),常用命令:member 是元素,score 是分?jǐn)?shù)
- ZADD key score1 member1 [score2 member2] 向有序集合添加一個或多個成員
- ZRANGE key start stop [WITHSCORES] 通過索引區(qū)間返回有序集合中指定區(qū)間內(nèi)的成員
- ZINCRBY key increment member 有序集合中對指定成員的分?jǐn)?shù)加上增量increment
- ZREM key member [member…] 移除有序集合中的一個或多個成員
通用命令
Reids的通用命令是不分?jǐn)?shù)據(jù)類型的,都可以使用的命令:
- KEYS pattern 查找所有符合給定模式(pattern)的key
- EXISTS key 檢查給定key是否存在
- TYPE key 返回key所儲存的數(shù)據(jù)類型
- DEL key 該命令用于在key存在時刪除key
?Java操作Redis
在Java項目中??梢允褂肧pring Data Redis來簡化操作
步驟:
1.導(dǎo)入Spring Data Redis的maven坐標(biāo)
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
2、配置Redis數(shù)據(jù)源
spring:redis:host: ${sky.redis.host}port: ${sky.redis.port}auth: ${sky.redis.auth}database: ${sky.redis.database}
sky:redis:host: localhostport: 6379auth: 325523 #密碼database: 0 #指定使用0號數(shù)據(jù)源
3、編寫配置類,創(chuàng)建RedisTemplate對象
package com.sky.config;import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;@Configuration
@Slf4j
public class RedisConfiguration {@Beanpublic RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory){log.info("開始創(chuàng)建Reids模版對象...");RedisTemplate redisTemplate = new RedisTemplate();//設(shè)置reids的連接工廠對象redisTemplate.setConnectionFactory(redisConnectionFactory);//設(shè)置redis key序列化器redisTemplate.setKeySerializer(new StringRedisSerializer());return redisTemplate;}
}
4、通過ReidsTemplate對象操作Redis
package com.sky.test;import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.*;import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;@SpringBootTest
public class SpringDataRedisTest {@Autowiredprivate RedisTemplate redisTemplate;@Testpublic void testRedisATemplate(){System.out.println(redisTemplate);ValueOperations valueOperations = redisTemplate.opsForValue();HashOperations hashOperations = redisTemplate.opsForHash();ListOperations listOperations = redisTemplate.opsForList();SetOperations setOperations = redisTemplate.opsForSet();ZSetOperations zSetOperations = redisTemplate.opsForZSet();}/*** 操作字符串?dāng)?shù)據(jù)類型*/@Testpublic void testString(){redisTemplate.opsForValue().set("city","北京");String city = (String) redisTemplate.opsForValue().get("city");System.out.println(city);redisTemplate.opsForValue().set("code","1234",3, TimeUnit.MINUTES);//設(shè)置3分鐘后過期redisTemplate.opsForValue().setIfAbsent("lock","1");//如果不存在才能設(shè)置redisTemplate.opsForValue().setIfAbsent("lock","2");}@Testpublic void testHash(){HashOperations hashOperations = redisTemplate.opsForHash();hashOperations.put("100","name","tom");//向哈希中插入鍵值對hashOperations.put("100","age","20");String name = (String)hashOperations.get("100", "name");//根據(jù)鍵獲取值System.out.println(name);Set keys = hashOperations.keys("100");//返回哈希中的所有鍵System.out.println(keys);List values = hashOperations.values("100");//返回哈希中的所有值System.out.println(values);hashOperations.delete("100","age");//根據(jù)鍵刪除鍵值對}
}
Spring Cache
簡介
Spring Cache是一個框架,實現(xiàn)了基于注解的緩存功能,只需要簡單地加一個注解,就能實現(xiàn)緩存功能
Spring Cache提供了一層抽象,底層可以切換不同的緩存實現(xiàn),例如:
- EHCache
- Caffeine
- Redis
在pom.xml中配置相關(guān)坐標(biāo)即可使用Spring Cache框架
常用注解
@EnableCaching | 開啟注解緩存功能,通常加在啟動類上 |
@Cacheable | 在方法執(zhí)行前先查詢緩存中是否有數(shù)據(jù),如果有數(shù)據(jù),則世界返回緩存數(shù)據(jù);如果沒有緩存數(shù)據(jù),調(diào)用方法并將方法返回值放到緩存中 |
@CachePut | 將方法的返回值放到緩存中 |
@CacheEvict | 將一條或多條數(shù)據(jù)從緩存中刪除 |
這些注解本質(zhì)是通過代理對象執(zhí)行的
項目應(yīng)用
思路
- 導(dǎo)入Spring Cache 和Redis的相關(guān)maven坐標(biāo)
- 在啟動類上加入@EnableCaching注解,開啟緩存注解功能
- 在用戶端接口SetmealController的list方法上加入@Cacheable注解
- 在管理端接口SetmealController的save、delete、update等方法上加入@CacheEvict注解
新增操作需要精確清理緩存(新增哪個就清理哪個)
刪、改操作需要清空全部緩存
查詢操作先在緩存中查,緩存中沒有再去數(shù)據(jù)庫中查,并把查詢結(jié)果放入緩存中
代碼實現(xiàn)
用戶端接口SetmealController
/*** 條件查詢* @param categoryId* @return*/@GetMapping("/list")@ApiOperation("根據(jù)分類id查詢套餐")@Cacheable(cacheNames = "setmealCache",key ="#categoryId")//key:setmealCache::categoryIdpublic Result<List<Setmeal>> list(Long categoryId) {Setmeal setmeal = new Setmeal();setmeal.setCategoryId(categoryId);setmeal.setStatus(StatusConstant.ENABLE);List<Setmeal> list = setMealService.list(setmeal);return Result.success(list);}
管理端接口SetmealController
/*** 新增套餐* @param setmealDTO* @return*/@PostMapping@ApiOperation("新增套餐")@CacheEvict(cacheNames = "setmealCache",key = "#setmealDTO.categoryId")public Result save(@RequestBody SetmealDTO setmealDTO){log.info("新增套餐:{}",setmealDTO);setMealService.saveWithDish(setmealDTO);return Result.success();}/*** 批量刪除套餐* @param ids* @return*/@DeleteMapping@ApiOperation("批量刪除套餐")@CacheEvict(cacheNames = "setmealCache",allEntries = true)//清空所有緩存public Result delete (@RequestParam List<Long> ids){log.info("批量刪除套餐:{}",ids);setMealService.delete(ids);return Result.success();}/*** 修改套餐* @param setmealDTO* @return*/@PutMapping@ApiOperation("修改套餐")@CacheEvict(cacheNames = "setmealCache",allEntries = true)//清空所有緩存public Result update(@RequestBody SetmealDTO setmealDTO){setMealService.update(setmealDTO);return Result.success();}/*** 起售停售菜品* @param status* @param id* @return*/@PostMapping("/status/{status}")@ApiOperation("起售停售菜品")@CacheEvict(cacheNames = "setmealCache",allEntries = true)//清空所有緩存public Result updateStatus(@PathVariable Integer status,Long id){setMealService.updateStatus(status,id);return Result.success();}