目前问题以及解决思路
- 请求数量过多,可能会受到浏览器的限制->用一个接口请求完所有的数据
{
user = userService.query
post = postService.query
picture = pictureService.query
return user + post + picture
}
- 请求不同的接口的参数可能不一致,增加前后端沟通成本->用一个参数把所有的参数统一,前端每次传固定的参数,后端对参数进行转换
{
统一传 searchText
后端把 searchText 转换为 userName => queryUser
}
- 前端写调用多个接口的代码,重复代码->用一个接口,不同参数来区分不同的数据源
{
前端传 type 调用后端同一个接口, 后端根据 type 调用不同的 service 查询
type = user => userService.query
}
后端
将分页查询用户的方法提取出来
将分页查询文章的方法提取出来
实现聚合搜索controller
@RestController
@RequestMapping("/search")
@Slf4j
public class SearchController {
@Resource
private PictureService pictureService;
@Resource
private UserService userService;
@Resource
private PostService postService;
/**
* 图片搜索
*
*/
@PostMapping("/all")
public BaseResponse<SearchVO> searchAll(@RequestBody SearchRequest
searchRequest,HttpServletRequest request) {
String searchText = searchRequest.getSearchText();
//图片
Page<Picture> picturePage =
pictureService.searchPicture(searchText, 1, 10);
//用户
UserQueryRequest userQueryRequest = new UserQueryRequest();
userQueryRequest.setUserName(searchText);
Page<UserVO> userVOPage =
userService.listUserVOByPage(userQueryRequest);
//文章
PostQueryRequest postQueryRequest = new PostQueryRequest();
postQueryRequest.setSearchText(searchText);
Page<PostVO> postVOPage =
postService.listPostVOByPage(postQueryRequest,request);
//聚合
SearchVO searchVO = new SearchVO();
searchVO.setUserList(userVOPage.getRecords());
searchVO.setPostList(postVOPage.getRecords());
searchVO.setPictureList(picturePage.getRecords());
return ResultUtils.success(searchVO);
}
}
修改为并发查询(线程池)
@PostMapping("/all")
public BaseResponse<SearchVO> searchAll(@RequestBody SearchRequest
searchRequest, HttpServletRequest request) {
String searchText = searchRequest.getSearchText();
//用户
CompletableFuture<Page<UserVO>> userTask =
CompletableFuture.supplyAsync(() -> {
UserQueryRequest userQueryRequest = new UserQueryRequest();
userQueryRequest.setUserName(searchText);
Page<UserVO> userVOPage =
userService.listUserVOByPage(userQueryRequest);
return userVOPage;
});
//文章
CompletableFuture<Page<PostVO>> postTask =
CompletableFuture.supplyAsync(() -> {
PostQueryRequest postQueryRequest = new PostQueryRequest();
postQueryRequest.setSearchText(searchText);
Page<PostVO> postVOPage =
postService.listPostVOByPage(postQueryRequest, request);
return postVOPage;
});
//图片
CompletableFuture<Page<Picture>> pictureTask =
CompletableFuture.supplyAsync(() -> {
Page<Picture> picturePage =
pictureService.searchPicture(searchText, 1, 10);
return picturePage;
});
//聚合
CompletableFuture.allOf(userTask, postTask, pictureTask).join();
try {
Page<UserVO> userVOPage = userTask.get();
Page<PostVO> postVOPage = postTask.get();
Page<Picture> picturePage = pictureTask.get();
SearchVO searchVO = new SearchVO();
searchVO.setUserList(userVOPage.getRecords());
searchVO.setPostList(postVOPage.getRecords());
searchVO.setPictureList(picturePage.getRecords());
return ResultUtils.success(searchVO);
} catch (Exception e) {
log.error("查询异常", e);
throw new BusinessException(ErrorCode.SYSTEM_ERROR, "查询异常");
}
}
并发前
并发后
wtf,还慢了,并发不一定快,短板效应,要以实际测试为准
前端
IndexPage完成代码
旧
//旧
const loadDataOld = (params: any) => {
const pictureQuery = {
...params,
searchText: params.text,
};
myAxios.post("/picture/search/page/vo",pictureQuery).then((res: any) => {
pictureList.value = res.records;
});
const postQuery = {
...params,
searchText: params.text,
};
myAxios.post("/post/list/page/vo", postQuery).then((res: any) => {
postList.value = res.records;
});
const userQuery = {
...params,
userName: params.text,
}
myAxios.post("/user/list/page/vo", userQuery).then((res: any) => {
userList.value = res.records;
});
};
新
//新
const loadData = (params: any) => {
const query = {
...params,
searchText: params.text,
};
myAxios.post("/search/all",query).then((res: any) => {
userList.value = res.userList;
pictureList.value = res.pictureList;
postList.value = res.postList;
});
};
怎么样,变化大吧,前端代码是不是显得很整洁