Spring boot开源项目之个人博客(13)—博客管理
1. 分页展示
这部分一共两个内容,一个带条件查询动态分页展示,一个是ajax页面局部动态更新。
- 带条件查询动态分页展示
博客管理比分类要复杂一些,需要根据高级查询条件筛选文章进行分页展示,在流程上是差不多的。
首先是把查询条件封装成一个对象BlogQuery
@Data
public class BlogQuery {
private String title;
private Long typeId;
private boolean recommend;
}
查询标题、分类、是否推荐3项。
然后,写一下dao层接口、service层接口和实现,这部分和分类是差不多的。主要的区别就在于查找博客列表的方法。先使dao层接口继承JpaSpecificationExecutor
public interface BlogRepository extends JpaRepository<Blog, Long>, JpaSpecificationExecutor<Blog> {
}
然后定义好service层接口
Page<Blog> listBlog(Pageable pageable, BlogQuery blog);
接口的实现方法
@Override
public Page<Blog> listBlog(Pageable pageable, BlogQuery blog) {
return blogRepository.findAll(new Specification<Blog>() {
@Override
public Predicate toPredicate(Root<Blog> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
List<Predicate> predicates = new ArrayList<>();
if (!"".equals(blog.getTitle()) && blog.getTitle() != null){
predicates.add(criteriaBuilder.like(root.<String>get("title"), "%" + blog.getTitle() + "%"));
}
if (blog.getTypeId() != null){
predicates.add(criteriaBuilder.equal(root.<Type>get("type").get("id"), blog.getTypeId()));
}
if (blog.isRecommend()){
predicates.add(criteriaBuilder.equal(root.<Boolean>get("recommend"), blog.isRecommend()));
}
criteriaQuery.where(predicates.toArray(new Predicate[predicates.size()]));
return null;
}
}, pageable);
}
Root<Blog> root
表示使用高级查询的对象,criteriaQuery、criteriaBuilder可以帮助我们很方便的完成条件的拼接。
最后在controller层定义回调方法
@GetMapping("/blogs")
public String blogs(@PageableDefault(size = 3, sort = {
"updateTime"}, direction = Sort.Direction.DESC) Pageable pageable,
Model model, BlogQuery blog){
model.addAttribute("types", typeService.listType());
model.addAttribute("page", blogService.listBlog(pageable, blog));
return "admin/blogs";
}
这里 model.addAttribute("types", typeService.listType());
是因为前段页面分类的条件筛选是通过一个dropdown实现的,所以需要把数据库中的Type查出来送到前端
<div class="ui selection dropdown">
<input type="hidden" name="typeId">
<i class="dropdown icon"></i>
<div class="default text">分类</div>
<div class="menu">
<div class="item" th:each="type : ${types}" th:data-value="${type.id}" th:text="${type.name}" data-value="1">错误日志</div>
</div>
</div>
通过 th:each
循环把所有的分类都加入到dropdown里,设置th:data-value
为分类的id,显示文字为分类的名称。
查到的数据都送到前端之后,在前端把数据都展示出来
<div id="table-container">
<table th:fragment="blogList" class="ui celled teal table">
<thead>
<tr>
<th></th>
<th>标题</th>
<th>类型</th>
<th>推荐</th>
<th>更新时间</th>
<th>操作</th>
</tr>
</thead