到这里,新闻管理系统的后台管理功能基本完成了,包括有
-
标签管理,包括增删改查,显示。
-
种类管理,包括增删改查,显示。
-
文章列表显示、搜索,文章内容、属性编辑和修改。
接下来要做的就是在主页中展示新闻列表。效果如下所示:
1 dao层接口
明确要展示文章的标题和一部分内容,以及最新的推荐文章列表。也就是根据是否推荐来获取若干个News对象,如下:
@Query("select n from News n where n.recommend=true")
List<News> findTop(Pageable pageable);
另外,要实现搜索功能,就要传递文章标题
2 Service层
2.1Service接口和实现
主要是两个服务方法,一个是传入Pageable页面规则,返回页面对象用于分页显示新闻,另一个是传入想要显示的新闻个数,返回新闻列表,不需要分页显示,所以不用Pageable类。第三个用于搜索,结果也是要分页显示的,这里的搜索条件封装成了一个字符串。
//主页显示新闻列表
Page<News> listNew(Pageable pageable);
//主页推荐最新新闻列表
List<News> ListRecommendNewTop(Integer size);
//全局搜索
Page<News> listNew(String query,Pageable pageable);
接口的实现如下:
@Override
public Page<News> listNew(Pageable pageable) {
return newRepository.findAll(pageable);
}
@Override
public List<News> ListRecommendNewTop(Integer size) {
Sort sort =Sort.by(Sort.Direction.DESC,"updateTime");
Pageable pageable= PageRequest.of(0,size,sort);
return newRepository.findTop(pageable);
}
//新闻管理中的列表 包含了查询
@Override
public Page<News> listNew(Pageable pageable, NewQuery newQuery) {
return newRepository.findAll(new Specification<News>() {
@Override
public Predicate toPredicate(Root<News> root, CriteriaQuery<?> cq, CriteriaBuilder cb) {
List<Predicate> predicates=new ArrayList<>();
if(!"".equals(newQuery.getTitle()) && newQuery.getTitle()!=null){
predicates.add(cb.like(root.<String>get("title"),"%"+newQuery.getTitle()+"%"));
}
if(newQuery.getTypeId()!=null){
predicates.add(cb.equal(root.get("type").get("id"),newQuery.getTypeId()));
}
if(newQuery.isRecommend()){
predicates.add(cb.equal(root.get("recommand"),newQuery.isRecommend()));
}
cq.where(predicates.toArray(new Predicate[predicates.size()]));
return null;
}
},pageable);
}
2.1 NewQuery类编写
这个类主要是用来限定查询条件的,只是用来拼接到查询语句中在数据库中进行条件查询。
package com.zr0726.news.vo;
public class NewQuery {
private String title;
private Long typeId;
private boolean recommend;
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public Long getTypeId() {
return typeId;
}
public void setTypeId(Long typeId) {
this.typeId = typeId;
}
public boolean isRecommend() {
return recommend;
}
public void setRecommend(boolean recommend) {
this.recommend = recommend;
}
@Override
public String toString() {
return "NewQuery{" +
"title='" + title + '\'' +
", typeId=" + typeId +
", recommend=" + recommend +
'}';
}
}
3 Controller层编写
由于首页要展示的内容包括了分页新闻、标签、种类等信息,这里在展示的时候都要先传递过去。
@GetMapping("/")
public String index(@PageableDefault(size=3,sort={"updateTime"},direction = Sort.Direction.DESC)
Pageable pageable, Model model){
model.addAttribute("page",newService.listNew(pageable));
model.addAttribute("types",typeService.listTypeTop(3));
model.addAttribute("tags",tagService.listTagTop(3));
model.addAttribute("recommendNews",newService.ListRecommendNewTop(3));
return "index";
}
通过query搜索
@PostMapping("/search")
public String search(@PageableDefault(size=3,sort = {"updateTime"},direction = Sort.Direction.DESC)Pageable pageable,
@RequestParam String query, Model model){
model.addAttribute("page",newService.listNew("%"+query+"%",pageable));
model.addAttribute("query",query);
return "search";
}
注意写搜索的时候这里PathVariable是带参数在uri里,不能直接写在PostMapping里。