データ ディクショナリはそれほど頻繁には変更されず、システムはより頻繁にデータ ディクショナリにアクセスするため、データを保存する必要があります。データ ディクショナリ内のキャッシュに保存して、データベースの負荷を軽減し、アクセス速度を向上させます。ここでは、システムの分散キャッシュミドルウェアとして Redis を使用します。
Spring Boot プロジェクトにはデフォルトで Spring Data Redis が統合されており、Spring Data Redis は Redis 用の非常に便利な操作テンプレート RedisTemplate を提供しており、接続プールの自動管理も可能です。
サービスベース モジュールに redis の依存関係を追加するSpring Boot 2.0 以降は、デフォルトの commons-pool2 接続プール
<!-- spring boot redis缓存引入 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <!-- 缓存连接池--> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-pool2</artifactId> </dependency> <!-- redis 存储 json序列化 --> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> </dependency> <dependency> <groupId>com.fasterxml.jackson.datatype</groupId> <artifactId>jackson-datatype-jsr310</artifactId> </dependency>
service-core
#spring の application.yml に次の構成を追加します。
redis:
ホスト: 192.168.100.100
ポート: 6379
データベース: 0
パスワード: 123456 #デフォルトは空です
タイムアウト: 3000ms #最大待機時間。例外が発生します。タイムアウトするとスローされます。それ以外の場合、リクエストは永久に待機します
lettuce:
pool:
max-active: 20 #最大接続数、負の値は制限なしを意味します、デフォルトは 8
max- wait: -1 #最大ブロッキング待機時間、負の値は制限なしを意味します、デフォルト -1
max-idle: 8 #最大アイドル接続、デフォルト 8
min-idle:0 #最小アイドル接続、デフォルト 0
Linux サーバーにリモートで接続します。ここではローカルの centos 仮想マシン上の Redis を使用します。
サービスを開始します
cd /usr/local/redis-5.0.7
bin/redis-server redis.conf
テスト クラス RedisTemplateTests を作成します
@SpringBootTest @RunWith(SpringRunner.class) public class RedisTemplateTests { @Resource private RedisTemplate redisTemplate; @Resource private DictMapper dictMapper; @Test public void saveDict(){ Dict dict = dictMapper.selectById(1); //向数据库中存储string类型的键值对, 过期时间5分钟 redisTemplate.opsForValue().set("dict", dict, 5, TimeUnit.MINUTES); } }
RedisTemplate がデフォルトであることがわかりましたキーと値の保存には JDK シリアル化メソッドが使用されており、可読性が低くなります
service-base に追加します。この構成ファイルで Redis シリアル化スキームを構成できます
@Configuration public class RedisConfig { @Bean public RedisTemplate<String, Object> redisTemplate(LettuceConnectionFactory redisConnectionFactory) { RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>(); redisTemplate.setConnectionFactory(redisConnectionFactory); //首先解决key的序列化方式 StringRedisSerializer stringRedisSerializer = new StringRedisSerializer(); redisTemplate.setKeySerializer(stringRedisSerializer); //解决value的序列化方式 Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class); //序列化时将类的数据类型存入json,以便反序列化的时候转换成正确的类型 ObjectMapper objectMapper = new ObjectMapper(); //objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); objectMapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL); // 解决jackson2无法反序列化LocalDateTime的问题 objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); objectMapper.registerModule(new JavaTimeModule()); jackson2JsonRedisSerializer.setObjectMapper(objectMapper); redisTemplate.setValueSerializer(jackson2JsonRedisSerializer); return redisTemplate; } }
テストを再度実行し、キーは文字列ストレージを使用し、値はjson ストレージを使用します
@Test public void getDict(){ Dict dict = (Dict)redisTemplate.opsForValue().get("dict"); System.out.println(dict); }
DictServiceImpl
注: Redis サーバーがダウンした場合、例外をスローせずに通常どおり実行する必要があります。次のプロセスにより、業務が正常に実行されます。
@Resource private RedisTemplate redisTemplate; @Override public List<Dict> listByParentId(Long parentId) { //先查询redis中是否存在数据列表 List<Dict> dictList = null; try { dictList = (List<Dict>)redisTemplate.opsForValue().get("srb:core:dictList:" + parentId); if(dictList != null){ log.info("从redis中取值"); return dictList; } } catch (Exception e) { log.error("redis服务器异常:" + ExceptionUtils.getStackTrace(e));//此处不抛出异常,继续执行后面的代码 } log.info("从数据库中取值"); dictList = baseMapper.selectList(new QueryWrapper<Dict>().eq("parent_id", parentId)); dictList.forEach(dict -> { //如果有子节点,则是非叶子节点 boolean hasChildren = this.hasChildren(dict.getId()); dict.setHasChildren(hasChildren); }); //将数据存入redis try { redisTemplate.opsForValue().set("srb:core:dictList:" + parentId, dictList, 5, TimeUnit.MINUTES); log.info("数据存入redis"); } catch (Exception e) { log.error("redis服务器异常:" + ExceptionUtils.getStackTrace(e));//此处不抛出异常,继续执行后面的代码 } return dictList; }
統合 Redis の概要:
(1)関連する依存関係のインポート;
(2) Redis 接続情報の構成;
(3) 接続のテスト、値のテスト、および値のストレージのテスト;
(4) シリアライザーの構成独自のニーズに応じて、それ以外の場合は、デフォルトで jdk シリアライザーが使用されます。
redis ビジネス概要:
(1) まず、redis に対応するキャッシュ情報があるかどうかをクエリし、存在する場合は実行せずに直接取得して返します。 (2) redis の場合は、何らかの理由で接続されています ダウンタイムがない場合は、この時点でエラー ログを出力し、データベースのクエリを続行します;
(2) そうでない場合は、データベースにクエリを実行し、データを Redis に保存してデータを返します。
以上がRedis キャッシュのサンプルコード分析の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。