perf: 优化缓存模块

提升可读性 & 减小内存占用
This commit is contained in:
xiongxiaoyang
2025-07-25 17:03:46 +08:00
parent 7e27456a65
commit c24c68ecaf
14 changed files with 173 additions and 130 deletions

View File

@@ -43,7 +43,7 @@ public class BookController extends BaseController {
* 查询首页小说设置列表数据
*/
@GetMapping("listBookSetting")
public RestResult<Map<Byte, List<BookSettingVO>>> listBookSetting() {
public RestResult<Map<String, List<BookSettingVO>>> listBookSetting() {
return RestResult.ok(bookService.listBookSettingVO());
}

View File

@@ -82,7 +82,7 @@ public class PageController extends BaseController {
@RequestMapping(path = {"/", "/index", "/index.html"})
public String index(Model model) {
//加载小说首页小说基本信息线程
CompletableFuture<Map<Byte, List<BookSettingVO>>> bookCompletableFuture = CompletableFuture.supplyAsync(
CompletableFuture<Map<String, List<BookSettingVO>>> bookCompletableFuture = CompletableFuture.supplyAsync(
bookService::listBookSettingVO, threadPoolExecutor);
//加载首页新闻线程
CompletableFuture<List<News>> newsCompletableFuture = CompletableFuture.supplyAsync(newsService::listIndexNews,

View File

@@ -16,9 +16,10 @@ public interface BookService {
/**
* 查询首页小说设置列表数据
*
* @return
* */
Map<Byte, List<BookSettingVO>> listBookSettingVO();
*/
Map<String, List<BookSettingVO>> listBookSettingVO();
/**
* 查询首页点击榜单数据

View File

@@ -1,6 +1,5 @@
package com.java2nb.novel.service.impl;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.pagehelper.PageHelper;
import com.java2nb.novel.core.cache.CacheKey;
import com.java2nb.novel.core.cache.CacheService;
@@ -25,7 +24,6 @@ import io.github.xxyopen.web.util.BeanUtil;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.client.utils.DateUtils;
import org.mybatis.dynamic.sql.SortSpecification;
import org.mybatis.dynamic.sql.render.RenderingStrategies;
@@ -48,7 +46,6 @@ import java.util.concurrent.ThreadPoolExecutor;
import java.util.stream.Collectors;
import static com.java2nb.novel.mapper.BookCategoryDynamicSqlSupport.bookCategory;
import static com.java2nb.novel.mapper.BookCategoryDynamicSqlSupport.sort;
import static com.java2nb.novel.mapper.BookCommentDynamicSqlSupport.bookComment;
import static com.java2nb.novel.mapper.BookContentDynamicSqlSupport.bookContent;
import static com.java2nb.novel.mapper.BookContentDynamicSqlSupport.content;
@@ -108,19 +105,19 @@ public class BookServiceImpl implements BookService {
@SneakyThrows
@Override
public Map<Byte, List<BookSettingVO>> listBookSettingVO() {
String result = cacheService.get(CacheKey.INDEX_BOOK_SETTINGS_KEY);
if (result == null || result.length() < Constants.OBJECT_JSON_CACHE_EXIST_LENGTH) {
List<BookSettingVO> list = bookSettingMapper.listVO();
if (list.size() == 0) {
public Map<String, List<BookSettingVO>> listBookSettingVO() {
List<BookSettingVO> list = cacheService.getList(CacheKey.INDEX_BOOK_SETTINGS_KEY, BookSettingVO.class);
if (list == null || list.isEmpty()) {
list = bookSettingMapper.listVO();
if (list.isEmpty()) {
//如果首页小说没有被设置,则初始化首页小说设置
list = initIndexBookSetting();
}
result = new ObjectMapper().writeValueAsString(
list.stream().collect(Collectors.groupingBy(BookSettingVO::getType)));
cacheService.set(CacheKey.INDEX_BOOK_SETTINGS_KEY, result, 3600 * 24);
cacheService.setObject(CacheKey.INDEX_BOOK_SETTINGS_KEY, list, 3600 * 24);
}
return new ObjectMapper().readValue(result, Map.class);
return list.stream().collect(
Collectors.groupingBy(book -> book.getType().toString())
);
}
@@ -170,11 +167,10 @@ public class BookServiceImpl implements BookService {
return new ArrayList<>(0);
}
@Override
public List<Book> listClickRank() {
List<Book> result = (List<Book>) cacheService.getObject(CacheKey.INDEX_CLICK_BANK_BOOK_KEY);
if (result == null || result.size() == 0) {
List<Book> result = cacheService.getList(CacheKey.INDEX_CLICK_BANK_BOOK_KEY, Book.class);
if (result == null || result.isEmpty()) {
result = listRank((byte) 0, 10);
cacheService.setObject(CacheKey.INDEX_CLICK_BANK_BOOK_KEY, result, 5000);
}
@@ -183,8 +179,8 @@ public class BookServiceImpl implements BookService {
@Override
public List<Book> listNewRank() {
List<Book> result = (List<Book>) cacheService.getObject(CacheKey.INDEX_NEW_BOOK_KEY);
if (result == null || result.size() == 0) {
List<Book> result = cacheService.getList(CacheKey.INDEX_NEW_BOOK_KEY, Book.class);
if (result == null || result.isEmpty()) {
result = listRank((byte) 1, 10);
cacheService.setObject(CacheKey.INDEX_NEW_BOOK_KEY, result, 3600);
}
@@ -193,8 +189,8 @@ public class BookServiceImpl implements BookService {
@Override
public List<BookVO> listUpdateRank() {
List<BookVO> result = (List<BookVO>) cacheService.getObject(CacheKey.INDEX_UPDATE_BOOK_KEY);
if (result == null || result.size() == 0) {
List<BookVO> result = cacheService.getList(CacheKey.INDEX_UPDATE_BOOK_KEY, BookVO.class);
if (result == null || result.isEmpty()) {
List<Book> bookPOList = listRank((byte) 2, 23);
result = BeanUtil.copyList(bookPOList, BookVO.class);
cacheService.setObject(CacheKey.INDEX_UPDATE_BOOK_KEY, result, 60 * 10);

View File

@@ -1,6 +1,5 @@
package com.java2nb.novel.service.impl;
import io.github.xxyopen.web.util.BeanUtil;
import com.java2nb.novel.service.FriendLinkService;
import com.java2nb.novel.core.cache.CacheKey;
import com.java2nb.novel.core.cache.CacheService;
@@ -31,16 +30,16 @@ public class FriendLinkServiceImpl implements FriendLinkService {
@Override
public List<FriendLink> listIndexLink() {
List<FriendLink> result = (List<FriendLink>) cacheService.getObject(CacheKey.INDEX_LINK_KEY);
if(result == null || result.size() == 0) {
SelectStatementProvider selectStatement = select(linkName,linkUrl)
.from(friendLink)
.where(isOpen,isEqualTo((byte)1))
.orderBy(sort)
.build()
.render(RenderingStrategies.MYBATIS3);
result = friendLinkMapper.selectMany(selectStatement);
cacheService.setObject(CacheKey.INDEX_LINK_KEY,result,60 * 60 * 24);
List<FriendLink> result = cacheService.getList(CacheKey.INDEX_LINK_KEY, FriendLink.class);
if (result == null || result.isEmpty()) {
SelectStatementProvider selectStatement = select(linkName, linkUrl)
.from(friendLink)
.where(isOpen, isEqualTo((byte) 1))
.orderBy(sort)
.build()
.render(RenderingStrategies.MYBATIS3);
result = friendLinkMapper.selectMany(selectStatement);
cacheService.setObject(CacheKey.INDEX_LINK_KEY, result, 60 * 60 * 24);
}
return result;
}

View File

@@ -4,7 +4,7 @@ import com.java2nb.novel.service.LikeService;
import jakarta.annotation.PostConstruct;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.scripting.support.StaticScriptSource;
import org.springframework.stereotype.Service;
@@ -20,7 +20,7 @@ import java.util.Collections;
@Slf4j
public class LikeServiceImpl implements LikeService {
private final RedisTemplate<Object, Object> redisTemplate;
private final StringRedisTemplate redisTemplate;
private DefaultRedisScript<Long> toggleLikeScript;
@@ -33,19 +33,19 @@ public class LikeServiceImpl implements LikeService {
public void init() {
// Lua 脚本保证原子性操作
String script = """
local key = KEYS[1]
local userId = ARGV[1]
local isLiked = redis.call('SISMEMBER', key, userId)
if isLiked == 1 then
redis.call('SREM', key, userId)
else
redis.call('SADD', key, userId)
end
return redis.call('SCARD', key)
""";
local key = KEYS[1]
local userId = ARGV[1]
local isLiked = redis.call('SISMEMBER', key, userId)
if isLiked == 1 then
redis.call('SREM', key, userId)
else
redis.call('SADD', key, userId)
end
return redis.call('SCARD', key)
""";
toggleLikeScript = new DefaultRedisScript<>();
toggleLikeScript.setScriptSource(new StaticScriptSource(script));
@@ -89,6 +89,6 @@ public class LikeServiceImpl implements LikeService {
}
private Long executeToggle(String key, Long userId) {
return redisTemplate.execute(toggleLikeScript, Collections.singletonList(key), userId);
return redisTemplate.execute(toggleLikeScript, Collections.singletonList(key), String.valueOf(userId));
}
}

View File

@@ -36,16 +36,16 @@ public class NewsServiceImpl implements NewsService {
@Override
public List<News> listIndexNews() {
List<News> result = (List<News>) cacheService.getObject(CacheKey.INDEX_NEWS_KEY);
if(result == null || result.size() == 0) {
SelectStatementProvider selectStatement = select(id, catName, catId, title,createTime)
.from(news)
.orderBy(createTime.descending())
.limit(2)
.build()
.render(RenderingStrategies.MYBATIS3);
List<News> result = cacheService.getList(CacheKey.INDEX_NEWS_KEY, News.class);
if (result == null || result.isEmpty()) {
SelectStatementProvider selectStatement = select(id, catName, catId, title, createTime)
.from(news)
.orderBy(createTime.descending())
.limit(2)
.build()
.render(RenderingStrategies.MYBATIS3);
result = newsMapper.selectMany(selectStatement);
cacheService.setObject(CacheKey.INDEX_NEWS_KEY,result,60 * 60 * 12);
cacheService.setObject(CacheKey.INDEX_NEWS_KEY, result, 60 * 60 * 12);
}
return result;
}
@@ -53,25 +53,25 @@ public class NewsServiceImpl implements NewsService {
@Override
public News queryNewsInfo(Long newsId) {
SelectStatementProvider selectStatement = select(news.allColumns())
.from(news)
.where(id,isEqualTo(newsId))
.build()
.render(RenderingStrategies.MYBATIS3);
.from(news)
.where(id, isEqualTo(newsId))
.build()
.render(RenderingStrategies.MYBATIS3);
return newsMapper.selectMany(selectStatement).get(0);
}
@Override
public PageBean<News> listByPage(int page, int pageSize) {
PageHelper.startPage(page,pageSize);
SelectStatementProvider selectStatement = select(id, catName, catId, title,createTime)
.from(news)
.orderBy(createTime.descending())
.build()
.render(RenderingStrategies.MYBATIS3);
PageHelper.startPage(page, pageSize);
SelectStatementProvider selectStatement = select(id, catName, catId, title, createTime)
.from(news)
.orderBy(createTime.descending())
.build()
.render(RenderingStrategies.MYBATIS3);
List<News> news = newsMapper.selectMany(selectStatement);
PageBean<News> pageBean = PageBuilder.build(news);
pageBean.setList(BeanUtil.copyList(news,NewsVO.class));
pageBean.setList(BeanUtil.copyList(news, NewsVO.class));
return pageBean;
}