1. SpringBoot整合Redis
1.1 整合入門案例
1.1.1 匯入jar包
<!--spring整合redis redisTemplate Spring封裝jedis高級API-->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
</dependency>
1.1.2 完成測驗案例

1.1.3 測驗基本命令
package com.jt.test;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.params.SetParams;
//@SpringBootTest
public class TestRedis {
//鏈接服務: IP地址:埠
@Test
public void testSetGet() throws InterruptedException {
Jedis jedis = new Jedis("192.168.126.129",6379);
jedis.flushAll(); //先清空redis快取
//1.存取redis
jedis.set("key1", "天天向上");
String value = jedis.get("key1");
System.out.println(value);
//2.判斷key是否存在
if(jedis.exists("key1")){
jedis.set("key1", "好好學習,天天向上");
}else{
jedis.set("key1", "天天開心");
}
//3.為key添加超時時間
jedis.expire("key1", 10);
Thread.sleep(2000);
System.out.println("剩余存活時間:"+jedis.ttl("key1"));
//4.撤銷剩余超時時間
jedis.persist("key1");
System.out.println("撤銷成功!!");
}
}
1.1.4 setNx/setEx/set命令
/**
* 需求: 如果資料不存在,則將資料修改
*/
@Test
public void testSetNx(){
Jedis jedis = new Jedis("192.168.126.129",6379);
jedis.set("key1", "aaa");
//如果key不存在,則賦值
jedis.setnx("key1", "測驗方法");
System.out.println(jedis.get("key1"));
}
/**
* 需求: 實作超時時間的設定與賦值操作的原子性.
* 考點: 為資料設定超時時間時,切記滿足原子性要求.
* 否則會出現key永遠不能洗掉的現象
*/
@Test
public void testSetEx(){
Jedis jedis = new Jedis("192.168.126.129",6379);
/*jedis.set("key2", "bbb");
jedis.expire("key2", 3);*/
//???資料超時之后一定會被洗掉嗎??? 錯的
jedis.setex("key2", 10, "bbb");
}
/**
* 需求: 如果資料存在時,才會修改資料,并且為資料添加超時時間10秒(原子性).
* 引數說明:
* NX: 只有資料不存在時,才會賦值.
* XX: 只有資料存在時,才會賦值.
* EX: 秒
* PX: 毫秒
*/
public void testSet(){
Jedis jedis = new Jedis("192.168.126.129",6379);
/* if(jedis.exists("key3")){
jedis.setex("key3",10 ,"ccc");
}*/
SetParams setParams = new SetParams();
setParams.xx().ex(10);
//將所有的操作采用原子性的方式進行控制
jedis.set("key3", "ccc", setParams);
}
1.1.5 測驗hash
/**
* HASH測驗
*/
@Test
public void testHash(){
Jedis jedis = new Jedis("192.168.126.129",6379);
jedis.hset("person", "id", "100");
jedis.hset("person", "name", "tomcat貓");
System.out.println(jedis.hgetAll("person"));
}
1.1.6 測驗List
/**
* LIST集合測驗
*/
@Test
public void testList(){
Jedis jedis = new Jedis("192.168.126.129",6379);
jedis.lpush("list", "1","2","3","4");
String value = jedis.rpop("list");
System.out.println(value);
}
1.1.7 測驗事務
/**
* Set集合測驗
* 1. sadd 新增元素
* 2. SCARD 獲取元素數量
* 3. SINTER key1 key2 獲取元素的交集
* 4. SMEMBERS set 獲取集合元素
* demo自己補一下
* * */
@Test
public void testMulti(){
Jedis jedis = new Jedis("192.168.126.129",6379);
//開啟事務
Transaction transaction = jedis.multi();
try {
transaction.set("a", "a");
transaction.set("b", "b");
//提交事務
transaction.exec();
}catch (Exception e){
//回滾事務
transaction.discard();
}
}
1.2 SpringBoot整合Redis
1.2.1 編輯properties組態檔

1.2.2 編輯配置類

1.3 ObjectMapperUtil實作
1.3.1 業務需求
說明:在業務中通常需要將業務物件轉化為JSON資料.需要通過工具API進行手動的轉化.
1.3.2 入門案例
public class TestObjectMapper {
//objectMapper入門案例
//2. 將JSON轉化為物件
@Test
public void testObject() throws JsonProcessingException {
//1. 將物件轉化為JSON
ItemDesc itemDesc = new ItemDesc();
itemDesc.setItemId(100L)
.setItemDesc("我是一個測驗資料")
.setCreated(new Date())
.setUpdated(itemDesc.getCreated());
ObjectMapper objectMapper = new ObjectMapper();
String json = objectMapper.writeValueAsString(itemDesc);
System.out.println(json);
//2.將JSON轉化為物件
ItemDesc desc = objectMapper.readValue(json, ItemDesc.class);
System.out.println(desc);
}
@Test
public void testList() throws JsonProcessingException {
List<ItemDesc> list = new ArrayList<>();
ItemDesc itemDesc = new ItemDesc();
itemDesc.setItemId(100L).setItemDesc("我是一個測驗資料").setCreated(new Date()).setUpdated(itemDesc.getCreated());
ItemDesc itemDesc2 = new ItemDesc();
itemDesc2.setItemId(200L).setItemDesc("我是一個測驗資料").setCreated(new Date()).setUpdated(itemDesc.getCreated());
list.add(itemDesc);
list.add(itemDesc2);
//1. 將物件轉化為JSON
ObjectMapper objectMapper = new ObjectMapper();
String json = objectMapper.writeValueAsString(list);
System.out.println(json);
//2.將JSON轉化為物件
List<ItemDesc> list2 = objectMapper.readValue(json,list.getClass());
System.out.println(list2);
}
}
1.3.3 編輯ObjectMapperUtil
public class ObjectMapperUtil {
private static final ObjectMapper MAPPER = new ObjectMapper();
public static String toJSON(Object target){
try {
return MAPPER.writeValueAsString(target);
} catch (JsonProcessingException e) {
e.printStackTrace();
//將檢查例外轉化為運行時例外.
throw new RuntimeException(e);
}
}
public static <T> T toObject(String json,Class<T> targetClass){
try {
return MAPPER.readValue(json, targetClass);
} catch (JsonProcessingException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
}
1.4 實作商品分類快取操作
1.4.1 編輯ItemController
/**
* 業務需求: 實作商品分類樹形結構展現
* url地址: http://localhost:8091/item/cat/list
* 引數: id= 父級節點的ID
* 回傳值: List<EasyUITree>
*/
@RequestMapping("/list")
public List<EasyUITree> findItemCatList(Long id){
//暫時只查詢一級商品分類資訊
long parentId = (id==null?0:id);
//return itemCatService.findItemCatList(parentId);
return itemCatService.findItemCatCache(parentId);
}
1.4.2 編輯ItemService
package com.jt.service;
import com.baomidou.mybatisplus.core.conditions.query.Query;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.jt.mapper.ItemCatMapper;
import com.jt.pojo.ItemCat;
import com.jt.util.ObjectMapperUtil;
import com.jt.vo.EasyUITree;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import redis.clients.jedis.Jedis;
import java.util.ArrayList;
import java.util.List;
@Service
public class ItemCatServiceImpl implements ItemCatService{
@Autowired
private ItemCatMapper itemCatMapper;
@Autowired(required = false) //類似于懶加載
private Jedis jedis;
@Override
public ItemCat findItemCatById(Long itemCatId) {
return itemCatMapper.selectById(itemCatId);
}
/**
* 1.根據parentId 查詢子級目錄資訊
* 2.獲取ItemCatList集合,之后將List集合轉化為VOList集合
* 3.回傳資料
* @param parentId
* @return
*/
@Override
public List<EasyUITree> findItemCatList(long parentId) {
QueryWrapper<ItemCat> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("parent_id", parentId);
List<ItemCat> catList = itemCatMapper.selectList(queryWrapper);
//2 list集合轉化
List<EasyUITree> treeList = new ArrayList<>(catList.size());
for (ItemCat itemCat : catList){
long id = itemCat.getId();
String text = itemCat.getName();
String state = itemCat.getIsParent()?"closed":"open"; //是父級,默認應該closed
EasyUITree easyUITree = new EasyUITree(id, text, state);
treeList.add(easyUITree);
}
return treeList;
}
/**
* 實作步驟:
* 1.先定義key ITEM_CAT_PARENT::0
* 2.先查詢快取
* 有 true 獲取快取資料之后,將JSON轉化為物件 之后回傳
* 沒有 false 應該查詢資料庫, 之后將資料保存到redis中. 默認30天超時.
* * @param parentId
* @return
*/
@Override
public List<EasyUITree> findItemCatCache(long parentId) {
Long startTime = System.currentTimeMillis();
List<EasyUITree> treeList = new ArrayList<>();
//1.定義key
String key = "ITEM_CAT_PARENT::"+parentId;
//2.從快取中獲取物件
if(jedis.exists(key)){
//存在 直接獲取快取資料,之后轉化為物件
String json = jedis.get(key);
treeList = ObjectMapperUtil.toObject(json,treeList.getClass());
System.out.println("查詢redis快取,獲取資料");
long endTime = System.currentTimeMillis();
System.out.println("耗時:"+(endTime-startTime)+"毫秒");
}else{
//不存在 應該先查詢資料庫,之后將資料保存到快取中.
treeList = findItemCatList(parentId);
String json = ObjectMapperUtil.toJSON(treeList);
jedis.setex(key, 7*24*60*60, json);
System.out.println("查詢資料庫獲取結果");
long endTime = System.currentTimeMillis();
System.out.println("耗時:"+(endTime-startTime)+"毫秒");
}
return treeList;
}
}
2.AOP實作Redis快取
2.1 AOP作用
利用AOP可以實作對方法(功能)的擴展.實作代碼的解耦.
2.2 切面組成要素
切面 = 切入點運算式 + 通知方法
2.2.1 切入點運算式
1).bean(bean的ID) 攔截bean的所有的方法 具體的某個類 粗粒度的.
2).within(包名.類名) 掃描某個包下的某個類 com.jt.* 粗粒度的.
3).execution(回傳值型別 包名.類名.方法名(引數串列)) 細粒度的
4).@annotation(包名.注解名) 細粒度的
2.2.2 通知方法
說明: 通知相互之間沒有順序可言. 每個通知方法都完成特定的功能,切記AOP的通知方法與目標方法之間的順序即可.
1).before 目標方法執行前
2).afterReturning 目標方法執行后
3).afterThrowing 目標方法執行拋出例外時執行.
4).after 不管什么情況,最后都要執行的.
上述四大通知型別,一般用來記錄程式的運行狀態的.(監控機制)
5).around 目標方法執行前后都要執行.
如果要對程式的運行軌跡產生影響,則首選around.
2.2.3 AOP入門案例
@Aspect //標識我是一個切面
@Component //將物件交給spring容器管理 cacheAOP
public class CacheAOP {
//切面 = 切入點運算式 + 通知方法
//運算式1: bean(itemCatServiceImpl) ItemCatServiceImpl類
//@Pointcut("bean(itemCatServiceImpl)")
//@Pointcut("within(com.jt.service.*)")
// .* 一級包下的類 ..* 所有子孫后代的包和類
//回傳值型別任意, com.jt.service包下的所有類的add方法引數型別任意型別
//寫引數型別時注意型別的大小寫
@Pointcut("execution(* com.jt.service..*.*(..))")
public void pointcut(){
}
/**
*
* joinPoint代表連接點物件,一般適用于前四大通知型別(除around之外的)
* 客人 路人
*/
@Before("pointcut()")
public void before(JoinPoint joinPoint){
//1.獲取目標物件
Object target = joinPoint.getTarget();
System.out.println(target);
//2.獲取目標物件的路徑 包名.類名.方法名
String className = joinPoint.getSignature().getDeclaringTypeName();
String methodName = joinPoint.getSignature().getName();
System.out.println("目標方法的路徑:"+(className+"."+methodName));
//3.獲取引數型別
System.out.println(Arrays.toString(joinPoint.getArgs()));
}
@Around("pointcut()")
public Object around(ProceedingJoinPoint joinPoint){
System.out.println("環繞通知執行");
Object data = null;
try {
data = joinPoint.proceed(); //執行目標方法
} catch (Throwable throwable) {
throwable.printStackTrace();
}
return data;
}
}
2.3 作業
通過自定義注解@CacheFind完成快取操作.

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/232030.html
標籤:java
