entity
与Mysql中表相对应:
@Data
@NoArgsConstructor
@AllArgsConstructor
public class HotSpot implements Serializable {
@JsonIgnore
private static final long serialVersionUID = 2333L;
private int id;
private int rank;
private String title;
private String link;
private String publicName;
private int hotNumber;
private String detail;
private String timestamp;
private int uId;
使用lombok省略构造方法,get与set方法的编写。因为不同网站的热点都只爬取这几个内容,所以一个entity就行。
mapper
使用Mybatis作为ORM
public interface HotSpotMapper {
/**
* 查找最新的消息
* @param hotSpot 那张表
* @param number 消息数
* @return 消息列表
*/
@Select("select * from " +
" (select * from ${hotSpot}_hot_list order by id DESC limit #{number}) as t " +
"order by rank")
List<HotSpot> queryLastTime(@Param("hotSpot") String hotSpot, @Param("number") int number);
}
这里select中自己写sql,更加灵活。需要根据传入不同的热榜名称查找不同的数据表,并且每个热榜的展示条数是不同的。数据库名使用${}进行直接代替,number可以使用#{}。因为最新的数据id总是最大的,所以根据主键id进行查找速度快。
service
方法接口:
public interface HotSpotService {
/**
* @param hotSpot 热榜名
* @param number 热点条数
* @return 热点数据
*/
public List<HotSpot> queryLastTime(String hotSpot, int number);
}
接口实现
@Service
public class HotSpotServiceImpl implements HotSpotService {
@Autowired
private HotSpotMapper hotSpotMapper;
@Override
@Cacheable(value = "HotSpotData", key="#hotSpot")
public List<HotSpot> queryLastTime(String hotSpot, int number) {
return hotSpotMapper.queryLastTime(hotSpot, number);
}
}
@Service
将类标记为服务,创建Bean。@Autowired
进行依赖注入。@Cacheable
会自动使用Redis缓存,Redis中存在缓存时不用查询数据库,没有时查询结果会放入Redis。value是cacheNames,key为自定义键,这里为热榜名称。最终在Redis中键的全名是#value::#key
。
Main类添加@EnableCaching
controller
@Controller
@RequestMapping("/detail")
public class GetHotSpotInfoController {
private static Logger logger = LoggerFactory.getLogger(GetHotSpotInfoController.class);
@Resource
HotSpotService hotSpotService;
@RequestMapping("/{hotSpot}")
public String getHotSpot(@PathVariable("hotSpot") String hotSpot, ModelMap map){
UserDetails userDetails = (UserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
String name = userDetails.getUsername();
logger.info("用户名=" + name + "&行为=查看"+hotSpot);
List<HotSpot> hotSpots = hotSpotService.queryLastTime(hotSpot, getNumber(hotSpot));
List<DisplayData> displayData = new ArrayList<>();
for(HotSpot hs: hotSpots){
String detail = hs.getDetail();
List<String> eachSentence = Arrays.asList(detail.split("\n"));
displayData.add(new DisplayData(hs.getRank(), hs.getTitle(), hs.getLink(), hs.getPublicName(),
hs.getHotNumber(), eachSentence));
}
map.addAttribute("hotSpot_data", displayData);
map.addAttribute("name", name);
map.addAttribute("type", hotSpot);
return "hotspot/detail";
}
/**
* 获得热榜条数
* @param hotSpot 热榜名
* @return 条数
*/
private int getNumber(String hotSpot){
switch (hotSpot){
case "weibo":
return 50;
case "niuke":
return 30;
case "hupu":
return 20;
case "juejin":
return 30;
default:
return 20;
}
}
}
@RequestMapping("/{hotSpot}")
可以根据热榜名进行匹配,即除去其他确定的Mapping路径,其他请求都会转到这,没有相应的热榜会报错。logger记录用户日志,用户后续分析。向Thymeleaf页面传入展示数据,用户名,热榜名。
DAO
@Data
@AllArgsConstructor
@NoArgsConstructor
public class DisplayData {
private int rank;
private String title;
private String link;
private String publicName;
private int hotNumber;
private List<String> eachSentence;
}
对于detail分段需要进行特殊处理。
网友评论