Redisのキャッシュ
@
簡単な紹介
Redisの高性能データベースのキー値であります
優位
高さの読み取りおよび書き込み操作のための強力な性能(読取速度が11万回/秒、書き込み速度は81000回/秒です)。
(バイナリ文字列、リスト、ハッシュ、セット、順序セットなど)は、より豊富なデータ型をサポートしています
特定の物事の能力(のいずれか正常に実行またはまったく実行されません)。
恵まれません
- 高速アクセス・メモリ・データベースではなく、ハードウェアのメモリリソースを消費します
注:シングルスレッドRedisの単なる例えば、このモジュール上の要求にネットワーク要求を処理するクライアント要求によると、それは処理すべきスレッド/プロセスが再開される永続。
Redisのは、キャッシュを導入しました
リンクをクリックしてウィンドウRedisのバージョンをダウンロードし、ダウンロードがうまく、あなたは通常、ソフトウェア、インストールからすなわちエキスの場所に入れは完了です。(現在のユーザーが書き込むことができるかどうかのディレクトリにファイルが、許可を読むことを注意は、例えば、ウィンドウCの下:\プログラムファイル(x86の )、 デフォルトでこのディレクトリは読み取り専用と書き込みする権限を管理者に、あなたがしたいときに実行Redisのリアルタイムでログファイルに書き込まれ、このディレクトリには、読み取りおよび書き込み権限なしに、操作が)失敗します
カタログからの抽出物には、Windowsの終わりであるとして、以下のようになり、クライアント、サーバーを開くには、exeファイルをダブルクリックします。
これはspringboot統合ですので、あなたがダブルクリックできるようにしないクローズCMDウィンドウのオープンを行い、サービス側を開くには、シリーズをのRedis。
pom.xmlに追加しました
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
application.propertiesに追加
# Redis
#Redis服务器地址
spring.redis.host=127.0.0.1
#Redis服务器连接端口
spring.redis.port=6379
# Redis服务器连接密码(默认为空)
spring.redis.password=
#Redis数据库索引(默认为0)
spring.redis.database=0
#连接池最大连接数(使用负值表示没有限制)
spring.redis.jedis.pool.max-active=50
#连接池最大阻塞等待时间(使用负值表示没有限制)
spring.redis.jedis.pool.max-wait=3000
#连接池中的最大空闲连接
spring.redis.jedis.pool.max-idle=20
#连接池中的最小空闲连接
spring.redis.jedis.pool.min-idle=5
#连接超时时间(毫秒)
spring.redis.timeout=4000
コードの戦闘
次に示す新しいディレクトリコードの後
ここでは、メインクラスの役割を説明するために、SpringbootはRedisのを動作させるためにRedisTemplateクラスを提供していますが、法律という名前のクラスを説明するコメントもないが、十分ではありません「あまりにも文字通り。」だから、RedisUtilは、いくつかの一般的に使用されるメソッドをカプセル化書いた、RedisConfigは主に自動的に注入シーケンス、コメントを追加し、中国の回避の歪みの問題の手動注入をデフォルトとします。
这里特别说一说 RedisUtil 类,搜索 springboot 和 redis 的文章,这个需要自己封装的类网上大多写的非常混乱,而且前后的封装逻辑不一致, 我估计是某位博主从至少三个人那里复制粘贴糅合起来的,然后大家都跟着这位博主复制粘贴,反而成了热门文章。我猜测大家看它是个工具类,而且六百行左右,大多没有仔细琢磨,能简单测试通过即可,但是稍加思考,发现问题真的不少,很容易误导那些喜欢 “拿来主义” 的 “萌新” 。
虽然我这个系列也是快速上手系列,但我理解的快速上手,就是把让人云里雾里的概念讲直白,然后先暂时跳过那些需要深入的,避免刚入手的畏难情绪,把整个操作流程写的清楚明白,给别人讲一千遍道一万句,不如让他对着现成的程序跑一遍,我一直认为:对着一片空白的屏幕学习程序,只会让人愈加焦虑,最好的办法是一边运行,一边深入。
所以我选取了 redis 五大类型中的String,Hash,Set,List,几乎覆盖每个类型,而 SortedSet 没有选取是因为这是有序的Set,可以自己类比。工具类我统一提供的是取值,添加值,删除值,命名规律绝对可以让你 “望文生义” ,其实还有很多方法,这里我不全写出来,是因为五大数据类型都有一堆方法,你不一定用得上,而且很占篇幅,在这里,授人以鱼不如授人以渔,你仔细看看 RedisUtil 的工具类,就会发现规律,比如操作String,大多是先调用opsForValue()方法,操作Hash,大多先调用opsForHash()方法,把项目源码下载到本地,idea里面点进去,就能看到相关的一堆方法。工具类只是重新调用了,换了个名字,加了些逻辑处理。
别看是热门文章就盲从,我举几个刚才说的问题,
还有这个的注释说明风格也不统一,给人的感觉看着容易云里雾里的,网上的工具类还用的都是这一个,真的是哭笑不得,大家抄来抄去,都是方案整合商,就不要……
下面开始代码示范
RedisController.java
package com.example.controller;
import com.example.service.IRedisService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
@RequestMapping("redis")
public class RedisController {
@Autowired
private IRedisService redisService;
@RequestMapping("/redisString")
public void redisString() {
this.redisService.redisString();
}
@RequestMapping("/redisHash")
public void redisHash() {
this.redisService.redisHash();
}
@RequestMapping("/redisSet")
public void redisSet() {
this.redisService.redisSet();
}
@RequestMapping("/redisList")
public void redisList() {
this.redisService.redisList();
}
@RequestMapping("/redisSortedSet")
public void redisSortedSet() {
//有序的set,故而省略
}
}
IRedisService.java
package com.example.service;
public interface IRedisService {
void redisString();
void redisHash();
void redisSet();
void redisList();
void redisSortedSet();
}
RedisServiceIml.java
package com.example.service;
import com.example.util.RedisUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.List;
import java.util.Set;
@Service("redisService")
public class RedisServiceIml implements IRedisService {
@Autowired
private RedisTemplate<String, Object> redisTemplate;
@Resource
private RedisUtil redisUtil;
public void redisString() {
//添加值
redisUtil.stringSet("AAA", "这是一个String类型的值");
//取值
Object value = redisUtil.stringGet("AAA");
System.out.println(value);
}
public void redisHash() {
//添加值
redisUtil.hashSet("BBB", "test1", "原hash值1");
redisUtil.hashSet("BBB", "test2", "新hash值1");
redisUtil.hashSet("BBB", "test1", "原hash值2");
redisUtil.hashSet("BBB", "test2", "新hash值2");
//取值
Object value1 = redisUtil.hashGet("BBB", "test1");
Object value2 = redisUtil.hashGet("BBB", "test2");
System.out.println(value1);
System.out.println(value2);
}
public void redisSet() {
//添值
redisUtil.setSet("CCC", "这是一组Set集合的第一个");
redisUtil.setSet("CCC", "这是一组Set集合的第二个");
redisUtil.setSet("CCC", "这是一组Set集合的第三个");
//取值
Set vaule = redisUtil.setGet("CCC");
System.out.println(vaule);
}
public void redisList() {
//添加值
redisUtil.listSet("DDD", "这是一组List集合的第一个");
redisUtil.listSet("DDD", "这是一组List集合的第二个");
redisUtil.listSet("DDD", "这是一组List集合的第三个");
//取值
List list = redisUtil.listGet("DDD", 0, -1);
System.out.println(list);
}
public void redisSortedSet() {
//有序的set,故而省略
}
}
RedisConfig.java
package com.example.config;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
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.*;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
@Configuration
@EnableCaching
public class RedisConfig extends CachingConfigurerSupport {
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
RedisTemplate<String, Object> template = new RedisTemplate<>();
// 配置连接工厂
template.setConnectionFactory(factory);
//序列化和反序列化redis中的值
Jackson2JsonRedisSerializer jackson = new Jackson2JsonRedisSerializer(Object.class);
//Java对象转换成JSON结构
ObjectMapper objectMapper = new ObjectMapper();
// 指定要序列化的域
objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
// 指定序列化输入的类型
objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson.setObjectMapper(objectMapper);
// 值采用json序列化
template.setValueSerializer(jackson);
//使用StringRedisSerializer来序列化和反序列化redis的key值
template.setKeySerializer(new StringRedisSerializer());
// 设置hash key和value序列化模式
template.setHashKeySerializer(new StringRedisSerializer());
template.setHashValueSerializer(jackson);
template.afterPropertiesSet();
return template;
}
}
RedisUtil.java
package com.example.util;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
@Component
public class RedisUtil {
@Autowired
private RedisTemplate<String, Object> redisTemplate;
//===============缓存相关方法===============
//指定缓存失效时间
public boolean expire(String key, long time) {
try {
if (time > 0) {
redisTemplate.expire(key, time, TimeUnit.SECONDS);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
//根据key获取过期时间,返回0代表为永久有效
public long getExpire(String key) {
return redisTemplate.getExpire(key, TimeUnit.SECONDS);
}
//===============数据类型为String的相关方法===============
//根据key值获取缓存值
public Object stringGet(String key) {
return key == null ? null : redisTemplate.opsForValue().get(key);
}
//根据key值存入数据类型为String的缓存值
public boolean stringSet(String key, Object value) {
try {
redisTemplate.opsForValue().set(key, value);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
//根据key值存入数据类型为String的缓存值并设置时间
public boolean stringSetWithTime(String key, Object value, long time) {
try {
if (time > 0) {
redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
} else {
expire(key, time);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
//删除缓存
public void stringDelete(String... key) {
if (key != null && key.length > 0) {
if (key.length == 1) {
redisTemplate.delete(key[0]);
} else {
redisTemplate.delete(CollectionUtils.arrayToList(key));
}
}
}
//===============数据类型为Hash的相关方法===============
//根据key和item获取缓存值
public Object hashGet(String key, String item) {
return redisTemplate.opsForHash().get(key, item);
}
//根据key和item存入数据类型为Hash的缓存值
public boolean hashSet(String key, String item, Object value) {
try {
redisTemplate.opsForHash().put(key, item, value);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
//根据key和item存入数据类型为Hash的缓存值并设置时间
public boolean hashSetWithTime(String key, String item, Object value, long time) {
try {
redisTemplate.opsForHash().put(key, item, value);
if (time > 0) {
expire(key, time);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
//删除缓存
public void hashDelete(String key, Object... item) {
redisTemplate.opsForHash().delete(key, item);
}
//===============数据类型为SET的相关方法===============
//根据key值获取缓存值
public Set<Object> setGet(String key) {
try {
return redisTemplate.opsForSet().members(key);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
//根据key值存入数据类型为SET的缓存值
public long setSet(String key, Object... values) {
try {
return redisTemplate.opsForSet().add(key, values);
} catch (Exception e) {
e.printStackTrace();
return 0;
}
}
//根据key值存入数据类型为SET的缓存值并设置时间
public long setSetWithTime(String key, long time, Object... values) {
try {
Long count = redisTemplate.opsForSet().add(key, values);
if (time > 0) {
expire(key, time);
}
return count;
} catch (Exception e) {
e.printStackTrace();
return 0;
}
}
//删除缓存
public long setDelete(String key, Object... values) {
try {
Long count = redisTemplate.opsForSet().remove(key, values);
return count;
} catch (Exception e) {
e.printStackTrace();
return 0;
}
}
//===============数据类型为LIST的相关方法===============
//获取List缓存的内容,从start到end,若从0到-1代表所有值
public List<Object> listGet(String key, long start, long end) {
try {
return redisTemplate.opsForList().range(key, start, end);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
//根据key值存入数据类型为List的缓存值
public boolean listSet(String key, Object value) {
try {
redisTemplate.opsForList().rightPush(key, value);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
//根据key值存入数据类型为List的缓存值并设置时间
public boolean listSetWithTime(String key, Object value, long time) {
try {
redisTemplate.opsForList().rightPush(key, value);
if (time > 0) {
expire(key, time);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
//删除缓存
public long listDelete(String key, long count, Object value) {
try {
Long remove = redisTemplate.opsForList().remove(key, count, value);
return remove;
} catch (Exception e) {
e.printStackTrace();
return 0;
}
}
}
プロジェクトを開始した後、ブラウザの入力にhttp:// localhost:8080 / Redisの/ redisString、(フロントデスクは文句を言うでしょう、この要求は唯一のトリガーのビジネスロジックの背景、無フロントページの表示ために)次のように操作文字列型のレンダリングがあります。
プロジェクトを開始した後、ブラウザの入力にhttp:// localhost:8080 / Redisの / redisHash、 ;(ノートは、私は、コードを書かなければならなかったが、4つの値を挿入することで、2つだけをプリントアウトし、ハッシュ演算式のレンダリングは次の通りですキー値と項目値ならば、新しい値)が元の値、およびコード比較チャート、お品物、おファインケミカルが上書きされますので。
プロジェクトを開始した後、ブラウザの入力にhttp:// localhost:8080 / Redisの/ redisSet、設定された動作種別図作用に示すように、(設定は順不同である)
プロジェクトを開始した後、ブラウザ入力のhttp:// localhostを:8080 / Redisの / redisList、 リスト操作式図の効果に示すように、
注:最初はそうユーザログインに割り当てられたアドレスを覚えて、春のセキュリティを設定しているので、紙が、来て一連の記事に基づいている場合。またはスーパー管理者アカウントの開口部が、あなたはこれらのアドレスにアクセスするには、管理者アカウントを使用して、任意のディレクトリのプロジェクトにアクセスすることができます。
これは、すべての学習シリーズの源である、そこに理解していない場合は、コンテンツをローカルにダウンロードすることができる、独自の実践的な操作を豊かにしたいです