以前の Web サイトに非常に簡単な最適化を行い、ユーザー リストにページング機能を追加しました。
ページ分割の際は読み込み速度を考慮することをお勧めします。ページを切り替えるのに数秒待たなければならない場合、エクスペリエンスは非常に悪くなります。
そこで、redis キャッシュを追加することを考えました。
springboot が redis を統合するには 2 つの方法があります:
1. アノテーションを使用します (@EnableCaching @Cacheable . . . など)
2. RedisTemplate を使用する
RedisTemplate を使用してキャッシュを操作すると、アノテーションを使用するよりも柔軟で便利です。アノテーションを使用すると、メソッドを入力せずにキャッシュから直接データをフェッチするため、理論的には高速になるはずです。 RedisTemplateをメソッド内で実行し、ロジックの記述の判定を行う必要があります。
以下は、ページングのキャッシュに関する私のアイデアの記録です。不足点はたくさんあると思います。皆さんに指摘していただければ幸いです。
ビジネス シナリオはバックエンド管理システムです。リアルタイムのデータ更新にあまり注意を払う必要はなく、有効期限を 1 時間に設定するだけです。
私のアイデアは次のとおりです:
初めてページを読み込むときに、データベースから最初の 4 ページのデータをクエリします。このようにして、初回は少し長く待ちます。その後のページ変更はほとんど待つ必要がなく、より良いエクスペリエンスになります。その後、ページを変更するたびにキャッシュにあるかどうかを確認し、役に立たない場合はキャッシュに追加します。
@RequestMapping("/appUser/{currentPage}") public R<String> getTableData1(@PathVariable int currentPage) { //第一次请求 前面几页用到的概率更大 把后面三页存入redis 减少后面分页请求的时间 以后每次加载页面都把那页放入redis // 设置一个小时过期 Page<AppUser> appUserPage = new Page<AppUser>(currentPage, 12); if (currentPage == 1 && !redisTemplate.hasKey(1)) { for (int i = 1; i < 5; i++) { Page<AppUser> redisPage = new Page<AppUser>(i, 12); redisTemplate.opsForValue().set(i, appUserServiceInterface.page(redisPage), 1, TimeUnit.HOURS); } } else if (!redisTemplate.hasKey(currentPage)) { redisTemplate.opsForValue().set(currentPage, appUserServiceInterface.page(appUserPage), 1, TimeUnit.HOURS); return R.success((Page<AppUser>) redisTemplate.opsForValue().get(currentPage)); } else if (redisTemplate.hasKey(currentPage)) { return R.success((Page<AppUser>) redisTemplate.opsForValue().get(currentPage)); } return R.success(appUserServiceInterface.page(appUserPage)); }
データ統計に再度注釈を付けてみました。
まず起動時に @EnableCaching アノテーションを追加します
アノテーションは簡単に使用できます。メソッドに @Cacheable を追加するだけです。メソッドを実行する前に、Redis キャッシュに対応するアノテーションがあるかどうかがクエリされます。キーがある場合は値を直接取得し、そうでない場合はメソッドを実行します。
value = "appUserData" はキャッシュ領域の名前、key はキーの名前です。
次のキー値は appUserData です: userArea
@RequestMapping ("/userArea") @Cacheable(value = "appUserData",key ="'userArea'") public R<String> area() { List<AppUser> userList = appUserServiceInterface.list(); List<String> areaList = new ArrayList<>(); for (AppUser appUser : userList) { areaList.add(appUser.getArea()); } //放入map记录每个月份出现的次数 Map<String, Integer> areaTimes = new HashMap<>(); for (String s : areaList) { if (!areaTimes.containsKey(s)) { areaTimes.put(s, 1); }else { areaTimes.put(s, areaTimes.get(s) + 1); } } //排序 //自定义比较器 Comparator<Map.Entry<String, Integer>> valCmp = new Comparator<Map.Entry<String, Integer>>() { @Override public int compare(Map.Entry<String, Integer> o1, Map.Entry<String, Integer> o2) { // TODO Auto-generated method stub return o2.getValue() - o1.getValue(); // 降序排序,如果想升序就反过来 } }; //将map转成List,map的一组key,value对应list一个存储空间 List<Map.Entry<String, Integer>> mapList = new ArrayList<Map.Entry<String, Integer>>(areaTimes.entrySet()); //传入maps实体 Collections.sort(mapList, valCmp); //取前8 int len = mapList.size(); for (int i = 0; i < len-8; i++) { mapList.remove(8); } Map<String, String> resMap = new HashMap<>(); for (Map.Entry<String, Integer> m : mapList) { resMap.put(m.getKey(), m.getValue().toString()); } return R.success(resMap); }
その他の注意事項:
@CachePut
以上がSpringBoot が @Cacheable と RedisTemplate を使用して Redis を統合する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。