ホームページ  >  記事  >  データベース  >  SpringBoot のカスタム キャッシュ アノテーションを通じてデータベース データを Redis にキャッシュする方法

SpringBoot のカスタム キャッシュ アノテーションを通じてデータベース データを Redis にキャッシュする方法

WBOY
WBOY転載
2023-06-01 13:49:061222ブラウズ

実装

最初にMysqlで新しいテーブルbus_studentを作成します

SpringBoot のカスタム キャッシュ アノテーションを通じてデータベース データを Redis にキャッシュする方法

次に、このテーブルに基づいてコード生成を使用し、フロントエンドのVueを使用します。 -end コード生成が結合された追加メニュー。

SpringBoot のカスタム キャッシュ アノテーションを通じてデータベース データを Redis にキャッシュする方法

#次にバックグラウンド コードに進みます。バックグラウンド フレームワークには、Redis を操作するための関連する依存関係とツール クラスが追加されています。

ただし、ここにアスペクトの依存関係を追加する必要もあります

        <!-- https://mvnrepository.com/artifact/org.springframework/spring-aspects --><dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aspects</artifactId>
            <version>4.3.14.RELEASE</version>
        </dependency>

次に、Redis キャッシュを追加するためのアノテーションを作成します

package com.ruoyi.system.redisAop;


import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;/*
 * @Author
 * @Description 新增redis缓存
 **/@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)public @interface AopCacheEnable {//redis缓存key    String[] key();//redis缓存存活时间默认值(可自定义)long expireTime() default 3600;

}

と、構成クラスが保存されている Redis キャッシュを削除するためのアノテーションを作成します

package com.ruoyi.system.redisAop;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;/*
 * @Description 删除redis缓存注解
 **/@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)public @interface AopCacheEvict {//redis中的key值    String[] key();
}

次に、新しいカスタム キャッシュ アスペクト固有の実装クラス CacheEnableAspect を作成します。

ストレージの場所

SpringBoot のカスタム キャッシュ アノテーションを通じてデータベース データを Redis にキャッシュする方法##

package com.ruoyi.system.redisAop;


import com.ruoyi.system.domain.BusStudent;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;/*
 * @Description 自定义缓存切面具体实现类
 **/@Aspect
@Componentpublic class CacheEnableAspect {

    @Autowiredpublic RedisTemplate redisCache;/**
     * Mapper层切点 使用到了我们定义的 AopCacheEnable 作为切点表达式。     */@Pointcut("@annotation(com.ruoyi.system.redisAop.AopCacheEnable)")public void queryCache() {
    }/**
     * Mapper层切点 使用到了我们定义的 AopCacheEvict 作为切点表达式。     */@Pointcut("@annotation(com.ruoyi.system.redisAop.AopCacheEvict)")public void ClearCache() {
    }

    @Around("queryCache()")public Object Interceptor(ProceedingJoinPoint pjp) {
        Object result = null;//注解中是否有#标识boolean spelFlg = false;//判断是否需要走数据库查询boolean selectDb = false;//redis中缓存的keyString redisKey = "";//获取当前被切注解的方法名Method method = getMethod(pjp);//获取当前被切方法的注解AopCacheEnable aopCacheEnable = method.getAnnotation(AopCacheEnable.class);//获取方法参数值Object[] arguments = pjp.getArgs();//从注解中获取字符串String[] spels = aopCacheEnable.key();for (String spe1l : spels) {if (spe1l.contains("#")) {//注解中包含#标识,则需要拼接spel字符串,返回redis的存储redisKeyredisKey = spe1l.substring(1) + arguments[0].toString();
            } else {//没有参数或者参数是List的方法,在缓存中的keyredisKey = spe1l;
            }//取出缓存中的数据result = redisCache.opsForValue().get(redisKey);//缓存是空的,则需要重新查询数据库if (result == null || selectDb) {try {
                    result =  pjp.proceed();//从数据库查询到的结果不是空的if (result != null && result instanceof ArrayList) {//将redis中缓存的结果转换成对象listList<BusStudent> students = (List<BusStudent>) result;//判断方法里面的参数是不是BusStudentif (arguments[0] instanceof BusStudent) {//将rediskey-students 存入到redisredisCache.opsForValue().set(redisKey, students, aopCacheEnable.expireTime(), TimeUnit.SECONDS);
                        }
                    }
                } catch (Throwable e) {
                    e.printStackTrace();
                }
            }
        }return result;
    }/*** 定义清除缓存逻辑,先操作数据库,后清除缓存*/@Around(value = "ClearCache()")public Object evict(ProceedingJoinPoint pjp) throws Throwable {//redis中缓存的keyMethod method = getMethod(pjp);// 获取方法的注解AopCacheEvict cacheEvict = method.getAnnotation(AopCacheEvict.class);//先操作dbObject result = pjp.proceed();// 获取注解的key值String[] fieldKeys = cacheEvict.key();for (String spe1l : fieldKeys) {//根据key从缓存中删除            redisCache.delete(spe1l);
        }return result;
    }/**
     * 获取被拦截方法对象     */public Method getMethod(ProceedingJoinPoint pjp) {
        Signature signature = pjp.getSignature();
        MethodSignature methodSignature = (MethodSignature) signature;
        Method targetMethod = methodSignature.getMethod();return targetMethod;
    }
}

ここの queryCache と ClearCache、およびカット ポイントに注意してください。 inside 式

は、カスタマイズされた 2 つの AopCacheEnable と AopCacheEvict にそれぞれ対応します。

その後、周囲の通知の queryCache メソッドが実行される前後で

cut メソッドのパラメーター、パラメーター内のキーを取得し、そのキーに従って Redis でクエリを実行します。

If 見つからない場合は、メソッドの戻り結果をオブジェクト List に変換し、redis に格納します。

##見つかった場合は、結果が返されます。

次に、このテーブルのクエリ メソッドとマッパー レイヤーを見つけます。たとえば、クエリの戻り結果を redis

    @AopCacheEnable(key = "BusStudent",expireTime = 40)public List<BusStudent> selectBusStudentList(BusStudent busStudent);

に保存する場合は、追加、編集、

    /**
     * 新增学生
     *
     * @param busStudent 学生
     * @return 结果     */@AopCacheEvict(key = "BusStudent")public int insertBusStudent(BusStudent busStudent);/**
     * 修改学生
     *
     * @param busStudent 学生
     * @return 结果     */@AopCacheEvict(key = "BusStudent")public int updateBusStudent(BusStudent busStudent);/**
     * 删除学生
     *
     * @param id 学生ID
     * @return 结果     */@AopCacheEvict(key = "BusStudent")public int deleteBusStudentById(Integer id);

ここでの注釈のキーは、上記のクエリの注釈のキーと一致している必要があることに注意してください。

プロンプトが表示されたら、プロジェクトを開始します。

Bean の 1 つを @Primary としてマークし、

コンシューマを更新してアクセスできるようにすることを検討してください。

#sringboot が @Autowired を介してインターフェイスの実装クラスを注入すると、複数の実装クラスがあることがわかります。つまり、このインターフェイスを継承するクラスが複数あり、Spring コンテナはどれを使用すればよいかわかりません。 。

Redis 構成クラスを見つけて、RedisTemplate に @Primary アノテーションを追加します。

SpringBoot のカスタム キャッシュ アノテーションを通じてデータベース データを Redis にキャッシュする方法

アノテーションの使用を確認します。

スタートアップ プロジェクトをデバッグします。 , in CacheEnableAspect 注釈内のブレークポイントをクエリし、クエリ メソッドを呼び出します。

SpringBoot のカスタム キャッシュ アノテーションを通じてデータベース データを Redis にキャッシュする方法ブレークポイントを入力できることがわかり、必要なロジックと効果に従って注釈を変更できます。

以上がSpringBoot のカスタム キャッシュ アノテーションを通じてデータベース データを Redis にキャッシュする方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はyisu.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。