16.好友推荐列表分页查询
好友推荐列表分页查询
一、请求dto对象
package com.tanhua.model.dto;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
//推荐好友列表分页查询请求参数
@Data
@NoArgsConstructor
@AllArgsConstructor
public class RecommendUserDto {
private Integer page = 1; //当前页数
private Integer pagesize = 10; //页尺寸
private String gender; //性别 man woman
private String lastLogin; //近期登陆时间
private Integer age; //年龄
private String city; //居住地
private String education; //学历
}
二、响应数据的模型对象
package com.tanhua.model.domain;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
import java.util.Collections;
import java.util.List;
//列表翻页查询
@Data
@AllArgsConstructor
@NoArgsConstructor
public class PageResult implements Serializable {
private Integer page;//当前页码
private Integer pagesize;//每页显示数
private Integer pages = 0;//总页数
private Integer counts = 0;//总记录数
private List<?> items = Collections.emptyList(); //列表
public PageResult(Integer page,Integer pagesize,
int counts,List list) {
this.page = page;
this.pagesize = pagesize;
this.items = list;
this.counts = counts;
this.pages = counts % pagesize == 0 ? counts / pagesize : counts / pagesize + 1;
}
}
三、TanHuaController
package com.tanhua.server.controller;
import com.tanhua.model.domain.PageResult;
import com.tanhua.model.dto.RecommendUserDto;
import com.tanhua.model.vo.TodayBest;
import com.tanhua.server.service.TanHuaService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/tanhua")
public class TanHuaController {
@Autowired
private TanHuaService tanHuaService;
/**
* 分页查询推荐好友列表
* 1.请求路径:/tanhua/recommendation
* 2.请求方式:get
* 3.请求参数:RecommendUserDto
* 4.响应数据:PageResult
*/
@GetMapping("/recommendation")
public ResponseEntity queryRecommendFriends(RecommendUserDto dto){
PageResult pageResult = tanHuaService.queryRecommendFriends(dto);
return ResponseEntity.ok(pageResult);
}
}
四、TanHuaService
package com.tanhua.server.service;
import com.tanhua.dubbo.api.RecommendUserApi;
import com.tanhua.dubbo.api.UserInfoApi;
import com.tanhua.model.domain.UserInfo;
import com.tanhua.model.dto.RecommendUserDto;
import com.tanhua.model.mongo.RecommendUser;
import com.tanhua.model.vo.PageResult;
import com.tanhua.model.vo.TodayBest;
import com.tanhua.server.interceptor.ThreadLocalUntils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
@Service
public class TanHuaService {
@DubboReference
private RecommendUserApi recommendUserApi;
@DubboReference
private UserInfoApi userInfoApi;
//查询今日佳人
public TodayBest queryToDayBest() {
//1.获取用户id
Long userId = ThreadLocalUntils.getUserId();
//2.调用api根据用户id查询今日佳人
RecommendUser recommendUser = recommendUserApi.queryBest(userId);
if(recommendUser == null){
recommendUser = new RecommendUser();
recommendUser.setUserId(1L);
recommendUser.setScore(90D);
}
//3.先得到今日佳人的用户id
Long toDayBestUserId = recommendUser.getUserId();
//4.调用api根据今日佳人的用户id查询用户详情
UserInfo userInfo = userInfoApi.queryUserInfo(toDayBestUserId);
//3.把recommendUser里的数据封装进ToDayBest
TodayBest todayBest = TodayBest.init(userInfo, recommendUser);
return todayBest;
}
//推荐好友的分页查询
public PageResult queryRecommendFriends(RecommendUserDto dto) {
//1.获取当前登录的用户id
Long userId = ThreadLocalUntils.getUserId();
//2.调用recommendUserApi分页查询当前登录用户的所有推荐好友
PageResult pageResult = recommendUserApi.queryRecommendFriends(dto.getPage(), dto.getPagesize(), userId);
//3.获取PageResult里面的推荐好友list集合数据列表
List<RecommendUser> recommendUsers = (List<RecommendUser>) pageResult.getItems();
//4.判断一下推荐好友集合是否为空,为空则直接返回pageResult
if(recommendUsers == null){
return pageResult;
}
//5.遍历推荐好友集合,得到每一个推荐好友,然后根据用户id调用UserInfoApi查询用户详情
List<TodayBest> recommendUserList = new ArrayList<>();
for (RecommendUser recommendUser : recommendUsers) {
//6.得到推荐好友的用户id,再查询用户详情
Long recommendUserUserId = recommendUser.getUserId();
UserInfo userInfo = userInfoApi.queryUserInfo(recommendUserUserId);
if(userInfo != null){
//7.构建vo对象
TodayBest todayBest = TodayBest.init(userInfo, recommendUser);
recommendUserList.add(todayBest);
}
}
//8.构造返回对象
pageResult.setItems(recommendUserList);
return pageResult;
}
}
五、RecommendUserApi接口实现类,提供者
- 1.构造Criter对象,设置查询条件
- 2.根据Criteria创建Query对象
- 3.查询总记录数
- 4.设置分页查询条件
- 5.构造返回数据
package com.tanhua.dubbo.api;
import com.tanhua.model.domain.PageResult;
import com.tanhua.model.mongo.RecommendUser;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import java.util.List;
@DubboService
public class RecommendUserApiImpl implements RecommendUserApi {
@Autowired
private MongoTemplate mongoTemplate;
//推荐好友的分页查询
public PageResult queryRecommendFriends(Integer page, Integer pagesize, Long toUserId) {
//1.构造Criter对象,设置查询条件
Criteria criteria = Criteria.where("toUserId").is(toUserId);
//2.根据Criteria创建Query对象
Query query = Query.query(criteria);
//3.查询总记录数
long count = mongoTemplate.count(query, RecommendUser.class);
//4.设置分页查询条件
query.with(Sort.by(Sort.Order.desc("score"))).skip((page - 1) * pagesize).limit(pagesize);
List<RecommendUser> recommendUsers = mongoTemplate.find(query, RecommendUser.class);
//5.构造返回数据
PageResult pageResult = new PageResult(page,pagesize, (int) count,recommendUsers);
return pageResult;
}
}
六、代码优化
频繁的调用UserInfo,会对dubbo提供者造成压力,也会影响性能;解决的方案就是一次性批量查询UserINfo
6.1UserInfoApi
//批量查询用户详情
Map<Long,UserInfo> batchQueryUserInfo(List<Long> ids,UserInfo userInfo);
6.2实现类
//批量查询UserInfo
public Map<Long, UserInfo> batchQueryUserInfo(List<Long> ids, UserInfo userInfo) {
//1.构建查询条件
QueryWrapper<UserInfo> qw = new QueryWrapper<>();
qw.in("id", ids);
//2.如果UserInfo不为空,添加条件
if (userInfo != null) {
if(!StringUtils.isEmpty(userInfo.getGender())){
qw.eq("gender",userInfo.getGender());
}
if(userInfo.getAge() != null){
qw.lt("age", userInfo.getAge());
}
}
//3.调用UserInfoMapper批量查询UserInfo
List<UserInfo> userInfosList = userInfoMapper.selectList(qw);
//4.把list集合转换为map集合
Map<Long, UserInfo> userInfosMap = CollUtil.fieldValueMap(userInfosList, "id");
return userInfosMap;
}
6.3TanHuaService
//推荐好友的分页查询
public PageResult queryRecommendFriends(RecommendUserDto dto) {
//1.获取当前登录的用户id
Long userId = ThreadLocalUntils.getUserId();
//2.调用recommendUserApi分页查询当前登录用户的所有推荐好友
PageResult pageResult = recommendUserApi.queryRecommendFriends(dto.getPage(), dto.getPagesize(), userId);
//3.获取PageResult里面的推荐好友list集合数据列表
List<RecommendUser> recommendUsers = (List<RecommendUser>) pageResult.getItems();
//4.判断一下推荐好友集合是否为空,为空则直接返回pageResult
if(recommendUsers == null){
return pageResult;
}
//5.批量获取所有推荐好友的用户id
List<Long> recommendUsersIds = CollUtil.getFieldValues(recommendUsers, "userId", Long.class);
//构造查询条件
UserInfo info = new UserInfo();
info.setGender(dto.getGender());
info.setAge(dto.getAge());
//6.调用批量查询推荐好友的用户详情
Map<Long, UserInfo> userInfoMap = userInfoApi.batchQueryUserInfo(recommendUsersIds, info);
//7.遍历recommendUsers
List<TodayBest> todayBestList = new ArrayList<>();
for (RecommendUser recommendUser : recommendUsers) {
Long recommendUserUserId = recommendUser.getUserId();
UserInfo userInfo = userInfoMap.get(recommendUserUserId);
if(userInfo != null){
TodayBest todayBest = TodayBest.init(userInfo, recommendUser);
todayBestList.add(todayBest);
}
}
//8.构造返回数据
pageResult.setItems(todayBestList);
return pageResult;
}