Enhance post search method

pull/89/head
johnniang 2019-01-31 22:44:11 +08:00
parent 20f7cf4812
commit 9ca3359221
6 changed files with 59 additions and 30 deletions

View File

@ -7,6 +7,7 @@ import cc.ryanc.halo.model.dto.Archive;
import org.springframework.data.domain.Page; import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Pageable;
import org.springframework.lang.NonNull; import org.springframework.lang.NonNull;
import org.springframework.lang.Nullable;
import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestParam;
import java.util.Date; import java.util.Date;
@ -86,7 +87,7 @@ public interface PostService {
* @return a page of posts * @return a page of posts
*/ */
@NonNull @NonNull
Page<Post> searchPostsBy(String keyword, String postType, Integer postStatus, @NonNull Pageable pageable); Page<Post> searchPostsBy(@Nullable String keyword, @Nullable String postType, @Nullable Integer postStatus, @NonNull Pageable pageable);
/** /**

View File

@ -22,14 +22,21 @@ import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.domain.Page; import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification; import org.springframework.data.jpa.domain.Specification;
import org.springframework.data.jpa.domain.Specifications;
import org.springframework.lang.NonNull; import org.springframework.lang.NonNull;
import org.springframework.lang.Nullable; import org.springframework.lang.Nullable;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate; import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.*; import java.util.*;
import static org.springframework.data.jpa.domain.Specification.where;
/** /**
* <pre> * <pre>
* *
@ -575,26 +582,49 @@ public class PostServiceImpl implements PostService {
} }
@NonNull @NonNull
private Specification<Post> buildSearchSepcification(@Nullable String keyword, @Nullable String postType, @Nullable Integer postStatus) { private Specification<Post> buildSearchSepcification(@NonNull String keyword,
return (Specification<Post>) (root, criteriaQuery, criteriaBuilder) -> { @NonNull String postType,
List<Predicate> predicates = new LinkedList<>(); @NonNull Integer postStatus) {
return Specification.where(postTitleLike(keyword)).or(postContentLike(keyword)).and(postTypeEqual(postType)).and(postStatusEqual(postStatus));
if (StringUtils.hasText(keyword)) { // return (root, criteriaQuery, criteriaBuilder) -> {
predicates.add(criteriaBuilder.like(root.get("postContent"), keyword)); // List<Predicate> predicates = new LinkedList<>();
} //
// if (StringUtils.hasText(keyword)) {
if (StringUtils.hasText(postType)) { // predicates.add(criteriaBuilder.like(root.get("postContent"), keyword));
predicates.add(criteriaBuilder.equal(root.get("postType"), postType)); // predicates.add(criteriaBuilder.or(criteriaBuilder.like(root.get("postTitle"), keyword)));
predicates.add(criteriaBuilder.or(criteriaBuilder.like(root.get("postType"), postType))); // }
} //
// if (StringUtils.hasText(postType)) {
if (postStatus != null) { // predicates.add(criteriaBuilder.equal(root.get("postType"), postType));
predicates.add(criteriaBuilder.equal(root.get("postStatus"), postStatus)); // }
predicates.add(criteriaBuilder.or(criteriaBuilder.like(root.get("postStatus"), postType))); //
} // if (postStatus != null) {
// predicates.add(criteriaBuilder.equal(root.get("postStatus"), postStatus));
return criteriaQuery.where(predicates.toArray(new Predicate[0])).getRestriction(); // }
}; //
// return criteriaQuery.where(predicates.toArray(new Predicate[0])).getRestriction();
// };
} }
private Specification<Post> postContentLike(@NonNull String keyword) {
Assert.hasText(keyword, "Keyword must not be blank");
return (root, criteriaQuery, criteriaBuilder) ->
criteriaBuilder.like(criteriaBuilder.lower(root.get("postContent")), "%" + keyword.toLowerCase() + "%");
}
private Specification<Post> postTitleLike(@NonNull String keyword) {
Assert.hasText(keyword, "Keyword must not be blank");
return (root, criteriaQuery, criteriaBuilder) ->
criteriaBuilder.like(criteriaBuilder.lower(root.get("postTitle")), "%" + keyword.toLowerCase() + "%");
}
private Specification<Post> postTypeEqual(@NonNull String postType) {
return (root, criteriaQuery, criteriaBuilder) -> criteriaBuilder.equal(root.get("postType"), postType);
}
private Specification<Post> postStatusEqual(@NonNull Integer postStatus) {
return (root, criteriaQuery, criteriaBuilder) -> criteriaBuilder.equal(root.get("postStatus"), postStatus);
}
} }

View File

@ -8,12 +8,10 @@ import cc.ryanc.halo.model.enums.ResultCodeEnum;
import cc.ryanc.halo.service.AttachmentService; import cc.ryanc.halo.service.AttachmentService;
import cc.ryanc.halo.service.LogsService; import cc.ryanc.halo.service.LogsService;
import cc.ryanc.halo.utils.LocaleMessageUtil; import cc.ryanc.halo.utils.LocaleMessageUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page; import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort; import org.springframework.data.domain.Sort;
import org.springframework.data.web.PageableDefault; import org.springframework.data.web.PageableDefault;

View File

@ -110,7 +110,8 @@ public class PostController extends BaseController {
@RequestParam(value = "keyword") String keyword, @RequestParam(value = "keyword") String keyword,
@PageableDefault(sort = "postId", direction = DESC) Pageable pageable) { @PageableDefault(sort = "postId", direction = DESC) Pageable pageable) {
try { try {
model.addAttribute("posts", postService.searchPosts(keyword, PostTypeEnum.POST_TYPE_POST.getDesc(), PostStatusEnum.PUBLISHED.getCode(), pageable)); Page<Post> posts = postService.searchPostsBy(keyword, PostTypeEnum.POST_TYPE_POST.getDesc(), PostStatusEnum.PUBLISHED.getCode(), pageable);
model.addAttribute("posts", posts);
} catch (Exception e) { } catch (Exception e) {
log.error("未知错误:{}", e.getMessage()); log.error("未知错误:{}", e.getMessage());
} }

View File

@ -73,7 +73,10 @@ public class FrontSearchController extends BaseController {
size = Integer.parseInt(HaloConst.OPTIONS.get(BlogPropertiesEnum.INDEX_POSTS.getProp())); size = Integer.parseInt(HaloConst.OPTIONS.get(BlogPropertiesEnum.INDEX_POSTS.getProp()));
} }
final Pageable pageable = PageRequest.of(page - 1, size, sort); final Pageable pageable = PageRequest.of(page - 1, size, sort);
final Page<Post> posts = postService.searchPosts(HtmlUtil.escape(keyword), PostTypeEnum.POST_TYPE_POST.getDesc(), PostStatusEnum.PUBLISHED.getCode(), pageable); final Page<Post> posts = postService.searchPostsBy(HtmlUtil.escape(keyword), PostTypeEnum.POST_TYPE_POST.getDesc(), PostStatusEnum.PUBLISHED.getCode(), pageable);
log.debug("Search posts result: [{}]", posts);
final int[] rainbow = PageUtil.rainbow(page, posts.getTotalPages(), 3); final int[] rainbow = PageUtil.rainbow(page, posts.getTotalPages(), 3);
model.addAttribute("is_search", true); model.addAttribute("is_search", true);
model.addAttribute("keyword", keyword); model.addAttribute("keyword", keyword);

View File

@ -54,8 +54,4 @@ spring:
# 多语言资源文件路径 # 多语言资源文件路径
messages: messages:
basename: i18n/messages basename: i18n/messages
logging:
file: ./logs/log.log