ホームページ >Java >&#&チュートリアル >Java SpringBootプロジェクトにRedisを統合する方法は何ですか?

Java SpringBootプロジェクトにRedisを統合する方法は何ですか?

王林
王林転載
2023-05-12 13:52:131534ブラウズ

Redis は完全にオープン ソースで、BSD プロトコルに準拠しており、高性能のキー/値データベースです。

Redis には、他のキー/値キャッシュ製品と比較して、次の 3 つの特徴があります。

  • Redis はデータの永続性をサポートしており、メモリ内のデータをディスクに保存し、再起動時に再ロードして使用できます。

  • Redis は、単純なキーと値の型のデータをサポートするだけでなく、リスト、セット、zset、ハッシュなどのデータ構造のストレージも提供します。

  • Redis はデータ バックアップ、つまりマスター/スレーブ モードでのデータ バックアップをサポートしています。

Redis の利点

  • 非常に高いパフォーマンス– Redis は 110,000 回/秒の速度で読み取り、81,000 回の速度で書き込みが可能/s s

  • 豊富なデータ型 - Redis は、バイナリの場合の String、List、Hash、Set、および zset データ型操作をサポートします。

  • アトミック – Redis のすべての操作はアトミックです。つまり、操作は正常に実行されるか、まったく実行されないかのどちらかです。個々の操作はアトミックです。複数の操作は、MULTI 命令と EXEC 命令によってラップされたトランザクション、つまりアトミック性もサポートします。

  • 豊富な機能– Redis はパブリッシュ/サブスクライブ、通知、キーの有効期限などの機能もサポートしています

  • Redis はシングルスレッド、6.0 このバージョンマルチスレッドの有効化をサポートします。

Redis のインストール

java SpringBoot项目整合Redis的方法是什么

ダウンロードした圧縮ファイルを解凍すると、解凍されたファイルの一覧は次のとおりです。

##cmd ウィンドウを使用して Redis を開きますjava SpringBoot项目整合Redis的方法是什么

redis-server.exe   redis.windows.conf   #加载配置文件启动

java SpringBoot项目整合Redis的方法是什么注: 開始後はウィンドウを閉じないでください。サービスは開始すると停止します。窓を閉めて!

Redis データベース クライアントのインストール

##ライブラリ関連の手順: java SpringBoot项目整合Redis的方法是什么

flushdb  清空当前库

flushall  清空所有库

select   1    切换库

主要な関連手順

手順関数#del1 つ以上のキーを削除します 1 つ以上のキーが存在するかどうかを確認します。複数のキーのうち 1 つが存在する場合は、1 が返されます。キーの生存時間の単位を設定します: 秒sパターンに一致するすべてのキーをクエリしますか? 1 文字と一致 * 0 ~ n 文字と一致 [] # のいずれかを満たす##キーを指定したライブラリに移動します#move keyname db##pexpirepexpire キー名ミリ秒を返しますttlttl keynamerandomkeyrandomkeyrenameキーの名前を変更 newkeytypetype keyname
構文
del キー名 存在します
exists keyname expire
expire keyname 秒 key
key * key h?llo move
キーの生存時間を設定します 単位: ミリ秒設定は成功した場合は 1 を返し、それ以外の場合は 0
戻りキー (秒単位) 残りの生存時間時刻、永続ストレージの場合は -1 を返し、キーが存在しない場合は -2 を返します
# #Return現在のデータベースからのランダム キー
キーの名前を変更し、正常に ok を返します。というエラーメッセージが返されます。
key に格納されている値の型を返します

Redis データ型

1.String (string)

  • string は Redis の最も基本的な型であり、Memcached とまったく同じ型として理解できます。 、キーは値に対応します。

  • 文字列型はバイナリ セーフです。これは、redis の文字列には任意のデータを含めることができることを意味します。たとえば、jpg 画像やシリアル化されたオブジェクトなどです。

  • 文字列型は Redis の最も基本的なデータ型で、文字列型の値は最大 512MB まで保存できます。

操作手順:

指定されたキーの値を設定しますGet キーの値を指定します。 キーの文字列値のサブ文字を返します指定されたキーの値を value に設定し、キーの古い値を返します。 値 value をキーに関連付け、キーの有効期限を秒 (秒単位) に設定します。 #SETNX STRLENMSETMSETNXINCRINCRBY##INCRBYFLOATDECR#DECRBYAPPEND
コマンド 説明
#SET
GET
GETRANGE
GETSET
SETEX
キーが存在しない場合にのみキーの値を設定します
key に格納されている文字列値の長さを返します。
1 つ以上のキーと値のペアを同時に設定します。
指定されたすべてのキーが存在しない場合に限り、1 つ以上のキーと値のペアを同時に設定します
キーに格納されている数値を 1 つ増やします
指定された増分値 (increment) をキーに格納されている値に加算します
キーを追加します 格納されている値指定された浮動小数点増分値 (increment) に加算されます。
キー 1 に格納されている数値を減少させます。
保存された値から指定された減分を差し引いた値
キーがすでに存在し、文字列である場合、APPEND コマンドは指定された値をキーの元の値の末尾に追加します # 2.ハッシュ (Hash)
Redis ハッシュは、キーと値 (key=>value) のペアのコレクションです。

  • Redis ハッシュは文字列型のフィールドと値のマッピング テーブルであり、オブジェクトの保存に特に適しています。

  • 操作手順:

コマンド

説明キーと値のペアを設定します#hgetキーに対応する値を取得しますhgetall##hdel#キー/値ペアの削除#hexistsキーが存在するかどうかを確認するhkeysすべてのキーを取得#複数のキーの値を取得するhsetnx存在しないキーの値を設定する
#hset
#すべてのキー/値ペアの取得
hvals すべての値を取得
hmset 複数のキー/値を設定##hmget
#hincrby 値 value に対して加算演算を行う
hincrbyfloat 値 value に対して浮動小数点型 value に対して加算演算を行う

3.List (リスト)

  • Redis リストは、挿入順に並べ替えられた文字列の単純なリストです。リストの先頭 (左) または末尾 (右) に要素を追加できます。

#操作手順

LINDEX# によってリスト内の要素を取得します##LINSERT キー BEFORE|AFTERLLEN#LPOP#外に移動してリストの最初の要素を取得しますリストの先頭に 1 つ以上の値を挿入します要素を取得しますリストの指定された範囲内 (0 -1)リストから重複する要素を削除しますインデックスを使用してリスト要素の値を設定しますが、インデックスが存在する必要があります。本質は、インデックスに基づいて値を変更することです#LTRIM リストをトリミングします。つまり、リストには指定された範囲内の要素のみが保持され、指定された範囲内にない要素は削除されます。削除されましたリストの最後の要素を削除します。戻り値は削除された要素です#リストに追加 1 つ以上の値既存のリストに値を追加
コマンド 説明
インデックス lindex リスト 0
リスト内の要素の前後に要素を挿入します
リストの長さを取得します
LPUSH
LPUSHX
既存の リスト ヘッダーに値を挿入します LRANGE
LREMM
LSET
#RPOP
##RPOPLPUSH リストの最後の要素を削除し、その要素を別のリストに追加して、
RPUSH## を返します。
RPUSHX
4.Set (セット) #Redis の Set は、文字列型の順序付けされていないコレクションです。
コレクションはハッシュ テーブルを通じて実装されるため、追加、削除、検索の複雑さは O(1) です。

  • 操作手順:

  • コマンド

  • 説明

#saddsmembersコレクション内のすべての要素を表示します (順序なし)コレクション内の要素の数を返します要素をランダムに返し、この要素を削除します要素をセットからセットに転送セットから削除セットにこの要素が含まれるかどうかを決定しますランダムに返します要素交差点の検索和集合の検索5.ZSet (ソートセット:順序付きセット) および Setこれは
コレクションに要素を追加します
scard
spop
smove
srem
sismember
srandmember
sinter
sunion
Redis ZSet
String

型要素のコレクションでもあり、重複するメンバーは許可されません。

  • 違いは、各要素が double タイプのスコアに関連付けられていることです。 Redis スコアによって、セット内のメンバーが小さいものから大きいものへと分類されます。

  • ZSet

    のメンバーは一意ですが、スコアは繰り返すことができます。 操作手順:

  • コマンド

    説明

#zadd順序付きセット要素を追加しますzcardセット内の要素の数を返しますzrange 昇順 zrevrange 降順 範囲内の要素を返す zrangebyscoreスコアによって範囲内の要素を検索する
#zrank ランキングに戻る
zrevrank フラッシュバックランキング
zscore 要素のスコアの表示
zrem 要素の削除
zincrby 特定の要素にポイントを追加します

SpringBoot 操作 Redis

  spring boot data redis中提供了RedisTemplate和StringRedisTemplate,其中StringRedisTemplate是Redistemplate的子类,两个方法基本一致,不同之处主要体现在操作的数据类型不同,RedisTemplate中的两个泛型都是Object,意味着存储的key和value都可以是一个对象,而StringRedisTemplate的两个泛型都是String,意味着StringRedisTemplate的key和value都只能是字符串。

引入依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

SpringBoot 配置 Redis

spring:
  redis:
    # Redis数据库索引(默认为0)
    database: 0
    # Redis服务器地址
    host: 127.0.0.1
    # Redis服务器连接端口
    port: 6379
    # Redis服务器连接密码(默认为空)
    password:
    # 连接池最大连接数(使用负值表示没有限制)
    jedis.pool.max-active: 20
    # 连接池最大阻塞等待时间(使用负值表示没有限制)
    jedis.pool.max-wait: -1
    # 连接池中的最大空闲连接
    jedis.pool.max-idle: 10
    # 连接池中的最小空闲连接
    jedis.pool.min-idle: 0
    # 连接超时时间(毫秒)
    timeout: 1000

RedisTemplate 及其相关方法

1.RedisTemplate 介绍

  Spring封装了RedisTemplate对象来进行对Redis的各种操作,它支持所有的Redis原生的api。RedisTemplate位于spring-data-redis包下。RedisTemplate提供了redis各种操作、异常处理及序列化,支持发布订阅。

2.Redis 5种数据结构操作

  • redisTemplate.opsForValue(); //操作字符串

  • redisTemplate.opsForHash(); //操作hash

  • redisTemplate.opsForList(); //操作list

  • redisTemplate.opsForSet(); //操作set

  • redisTemplate.opsForZSet(); //操作有序set

或者:

  • redistempalate.boundValueOps

  • redistempalate.boundSetOps

  • redistempalate.boundListOps

  • redistempalate.boundHashOps

  • redistempalate.boundZSetOps

 opsForXXX和boundXXXOps的区别:XXX为value的类型,前者获取一个operator,但是没有指定操作的对象(key),可以在一个连接(事务)内操作多个key以及对应的value;后者获取了一个指定操作对象(key)的operator,在一个连接(事务)内只能操作这个key对应的value。

 SpringBootTest 实现Redis数据库增删改查

/**
 * 使用RedisTemplate 操作Redis数据的不同数据类型
 */
@SpringBootTest
public class Springbootday03ApplicationTests {
    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    /**
     * String 类型数据操作
     */
    @Test
    public void operateString() {

        //添加值
        redisTemplate.opsForValue().set("str", "strValue1");

        //添加值  判定是否存在 存在则不添加
        Boolean aBoolean = redisTemplate.opsForValue().setIfAbsent("str", "strAbsent");
        System.out.println("str设置成功:" + aBoolean);

        //获取值
        String str = redisTemplate.opsForValue().get("str");
        System.out.println("str = " + str);

        //更新值
        redisTemplate.opsForValue().set("str", "strValue2");
        str = redisTemplate.opsForValue().get("str");
        System.out.println("newStr = " + str);

        //删除值
        Boolean b = redisTemplate.delete("str");
        System.out.println("str删除成功:" + b);

    }

    /**
     * 操作string类型数据  设置过期时间
     */
    @Test
    public void operateString2() {
        redisTemplate.opsForValue().set("str", "strTimeout", 10, TimeUnit.SECONDS);
        //判定值是否存在 不存在则设置值 同时设置过期时间
        Boolean aBoolean = redisTemplate.opsForValue().setIfAbsent("str2", "strTimeoutAbsent", 20, TimeUnit.SECONDS);
        System.out.println("setIfAbsent:" + aBoolean);
    }

    /**
     * 操作hash类型数据
     */
    @Test
    public void operateHash() {
        //添加hash类型数据  key - value
        redisTemplate.opsForHash().put("hash", "username", "admin");
        //修改hash类型数据
        redisTemplate.opsForHash().put("hash", "username", "tom");
        redisTemplate.opsForHash().put("hash", "password", "123456");

        //添加hash类型数据  key - map
        HashMap<String, String> map = new HashMap<>();
        map.put("driverName", "com.mysql.jdbc.Driver");
        map.put("url", "jdbc:mysql://localhost:3306/mybatis?serverTimezone=UTC");
        redisTemplate.opsForHash().putAll("hash", map);

        //获取hash类型数据  entries
        Map<Object, Object> hash = redisTemplate.opsForHash().entries("hash");
        hash.forEach((key, value) -> {
            System.out.println(key + "::" + value);
        });

        //获取所有的key
        Set<Object> keys = redisTemplate.opsForHash().keys("hash");
        for (Object key : keys) {
            System.out.println("key:" + key);
        }
        //获取所有value
        List<Object> values = redisTemplate.opsForHash().values("hash");
        values.forEach(value -> System.out.println("value:" + value));

        //删除hash类型数据  删除一个  返回删除的个数
        Long delete = redisTemplate.opsForHash().delete("hash", "username");
        System.out.println("delete = " + delete);

        //删除hash类型数据  删除多个  返回删除的个数
        delete = redisTemplate.opsForHash().delete("hash", "username", "password", "driverName");
        System.out.println("delete = " + delete);

        //删除hash类型数据  删除所有
        Boolean delHash = redisTemplate.delete("hash");
        System.out.println("delHah:" + delHash);

    }

    /**
     * 操作List类型  有序 可重复
     */
    @Test
    public void operateList() {

        //左压栈
        // redisTemplate.opsForList().leftPush("list", "listValue1");
        // redisTemplate.opsForList().leftPush("list", "listValue1");
        // redisTemplate.opsForList().leftPush("list", "listValue2");
        // redisTemplate.opsForList().leftPush("list", "listValue3");

        //右压栈
        redisTemplate.opsForList().rightPush("list", "listValue0");
        redisTemplate.opsForList().rightPush("list", "listValue2");
        redisTemplate.opsForList().rightPush("list", "listValue0");

        //左出栈
        String list1 = redisTemplate.opsForList().leftPop("list");
        System.out.println("leftPop list1 = " + list1);
        //右出栈
        String list2 = redisTemplate.opsForList().rightPop("list");
        System.out.println("rightPop list2 = " + list2);

        //获取所有数据
        List<String> lists = redisTemplate.opsForList().range("list", 0, 		        redisTemplate.opsForList().size("list") - 1);
        lists.forEach(list -> System.out.println(list));


        //设置指定位置的数据
        redisTemplate.opsForList().set("list", 0, "listValue0");
        /**
         * 从存储在键中的列表中删除等于值的元素的第一个计数事件。
         * count> 0:删除等于从左到右移动的值的第一个元素;
         * count< 0:删除等于从右到左移动的值的第一个元素;
         * count = 0:删除等于value的所有元素。
         */
        Long remove = redisTemplate.opsForList().remove("list", -1, "listValue0");
        System.out.println("remove:" + remove);

        //删除指定key的list数据
        Boolean list = redisTemplate.delete("list");
        System.out.println("list集合删除成功:" + list);
    }

    /**
     * 操作Set类型  无序 不可重复
     */
    @Test
    public void operateSet() {

        //设置set值
        redisTemplate.opsForSet().add("set", "setValue0");
        redisTemplate.opsForSet().add("set", "setValue0");
        redisTemplate.opsForSet().add("set", "setValue1");

        //判定是否包含
        Boolean member = redisTemplate.opsForSet().isMember("set", "setValue0");
        System.out.println("isMember:" + member);

        //删除set中的值
        Long remove = redisTemplate.opsForSet().remove("set", "setValue0");
        System.out.println("remove = " + remove);

        //获取set类型值
        Set<String> set = redisTemplate.opsForSet().members("set");
        set.forEach(str -> {
            System.out.println("str = " + str);
        });
    }

    /**
     * 操作 ZSet  有序 不可重复
     */
    @Test
    public void operateZSet() {
        //存储值
        Boolean add = redisTemplate.opsForZSet().add("zset", "zsetValue0", 10);
        System.out.println("add = " + add);
        System.out.println("add = " + add);
        add = redisTemplate.opsForZSet().add("zset", "zsetValue2", 2);
        System.out.println("add = " + add);
        //获取值
        // Boolean zset = redisTemplate.delete("zset");
        // System.out.println("delete zset = " + zset);
    }
}

Redis工具类的封装

/**
 * Redis 工具类
 * @author mosin
 * date 2021/11/30
 * @version 1.0
 */
@Component
public final class RedisUtil {

    private RedisUtil(){};
    @Autowired
    private RedisTemplate<String,String> redisTemplate;

    //设置值
    public void  setValue(String key,String value){
        redisTemplate.opsForValue().set(key, value);
    }
    // 设置值 同时设置有效时间
    public void setValue(String key, String value, Long timeOut, TimeUnit timeUnit){
        redisTemplate.opsForValue().setIfAbsent(key, value, timeOut, timeUnit);
    }

    //设置值 没有则设置 有则不设置
    public void  setNx(String key,String value){
        redisTemplate.opsForValue().setIfAbsent(key, value);
    }

    //设置值 没有则设置 同时设置有效时间 有则不设置
    public void  setNx(String key,String value,long timeOut,TimeUnit timeUnit){
        redisTemplate.opsForValue().setIfAbsent(key, value,timeOut,timeUnit);
    }

    //删除值
    public boolean del(String key){
        return redisTemplate.delete(key);
    }
    
     //获取值
    public String getValue(String key){
        return  redisTemplate.opsForValue().get(key);
    }
}

Redis 业务实践

redis 存储 token,实现非法请求拦截

1.编写拦截器

@Component
public class AdminInterceptor implements HandlerInterceptor {
    @Autowired
    private RedisUtil redisUtil;
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("拦截器以拦截请求");
        //从请求头中获取token  验证用户是否登录
        String token = request.getHeader("token");
        System.out.println(token);
        String tokenValue = redisUtil.getValue(token);
        System.out.println("tokenValue = " + tokenValue);
        if(tokenValue!=null){ //用户已登录 放行请求
            return  true;
        }else{//重定向到登录页面
            response.sendRedirect(request.getContextPath()+"/login.jsp");
            return false;
        }
    }
}

2.配置拦截器

@Configuration
public class LoginConfig implements WebMvcConfigurer {
    @Autowired
    private AdminInterceptor adminInterceptor;
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        InterceptorRegistration registration = registry.addInterceptor(adminInterceptor);
        registration.addPathPatterns("/**");
        registration.excludePathPatterns("/user/login","/user/register","/login.jsp");
    }
}

3.编写统一返回数据格式类

@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class JsonResult<T> {
    private Integer code;
    private String msg;
    private Long count;
    private T data;
}

4.编写控制器

@Controller
@RequestMapping("/user")
public class UserController {
    @Autowired
    private UserService userService;
    @Autowired
    private RedisUtil redisUtil;
    @ResponseBody
    @RequestMapping("/login")
    public Object login(User user) throws JsonProcessingException {
        User usr = User.builder().id(1).name("admin").password("123456").build();
        //获取token  放入redis
        String token = UUID.randomUUID().toString().replace("-", "");
        //将user 转为json格式放入 redis
        ObjectMapper objectMapper = new ObjectMapper();
        String s1 = objectMapper.writeValueAsString(usr);
        //将 token 和用户信息存入 redis
        redisUtil.setValue(token, s1, 2L, TimeUnit.MINUTES);
        //将token 存入map集合返回
        HashMap<String, String> map = new HashMap<>();
        map.put("token", token);
        return map;
    }

    @ResponseBody
    @RequestMapping("/register")
    public Object register(User user){
        HashMap<String, String> map = new HashMap<>();
        map.put("msg", "ok");
        return map;
    }

    @ResponseBody
    @RequestMapping("/add")
    public Object add(User user){
        HashMap<String, String> map = new HashMap<>();
        map.put("msg", "ok");
        return map;
    }
}

5.编写业务类和Mapper接口

6.使用postman接口测试工具测试接口

以上がJava SpringBootプロジェクトにRedisを統合する方法は何ですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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