接下来实现读取数据并在网页上以列表形式显示的功能。首先添加一些测试数据:
List<IndexQuery> indexQueries = Arrays.asList(
new IndexQueryBuilder().withObject(new Blog(1, "Mary Jones", "Jane is an expert in her field", 80, parseDate("2019-06-21"))).build(),
new IndexQueryBuilder().withObject(new Blog(2, "Jane Smith", "I am starting to get the hang of this...", 0, parseDate("2019-06-20"))).build(),
new IndexQueryBuilder().withObject(new Blog(3, "John Smith", "The Query DSL is really powerful and flexible", 100, parseDate("2019-06-20"))).build(),
new IndexQueryBuilder().withObject(new Blog(4, "Mary Jones", "Still trying this out...", 0, parseDate("2019-06-20"))).build(),
new IndexQueryBuilder().withObject(new Blog(5, "Mary Jones", "However did I manage before Elasticsearch?", 200, parseDate("2019-06-19"))).build(),
new IndexQueryBuilder().withObject(new Blog(6, "Jane Smith", "I like to collect rock albums", 0, parseDate("2019-06-19"))).build(),
new IndexQueryBuilder().withObject(new Blog(7, "Douglas Fir", "I like to build cabinets", 50, parseDate("2019-06-19"))).build(),
new IndexQueryBuilder().withObject(new Blog(8, "John Smith", "I love to go rock climbing", 40, parseDate("2019-06-18"))).build(),
new IndexQueryBuilder().withObject(new Blog(9, "Mary Jones", "I am Mary Jones, welcome to my blog!", 500, parseDate("2019-06-17"))).build(),
new IndexQueryBuilder().withObject(new Blog(10, "Mary Jones", "My first blog entry", 400, parseDate("2019-06-17"))).build()
);
elasticsearchTemplate.bulkIndex(indexQueries);
- 空查询
读取全部数据用matchAllQuery查询,controller代码:
@Autowired
private ElasticsearchTemplate elasticsearchTemplate;
@RequestMapping("/blogs")
public String query(Model model) {
SearchQuery searchQuery = new NativeSearchQueryBuilder()
.withQuery(QueryBuilders.matchAllQuery())
.build();
Page<Blog> blogs = elasticsearchTemplate.queryForPage(searchQuery, Blog.class);
model.addAttribute("blogs", blogs.getContent());
return "index";
}
页面代码同使用关系型数据库的方式完全相同,主要代码:
<div class="post" th:each="blog,blogStat:${blogs}">
<div class="user-block">
<span class="username" style="margin-left: 0px">
<a href="#" th:utext="${blog.author}">Jonathan Burke Jr.</a>
</span>
<span class="description" style="margin-left: 0px"
th:text="${#dates.format(blog.date,'yyyy-MM-dd HH:mm:ss')}"></span>
</div>
<p th:utext="${blog.text}"></p>
<ul class="list-inline">
<li><a class="btn btn-default btn-xs" th:href="@{'javascript:like(\'' + ${blog.id} + '\')'}"><i class="fa fa-thumbs-o-up"></i> 点赞</a>
</li>
<li class="pull-right"><span th:id="likes + ${blog.id}" th:text="${blog.likes}"></span>赞</li>
</ul>
</div>
效果如下:
- 排序
继续添加按日期倒序排序功能,只需增加一行代码:
SearchQuery searchQuery = new NativeSearchQueryBuilder()
.withQuery(QueryBuilders.matchAllQuery())
.withSort(SortBuilders.fieldSort("date").order(SortOrder.DESC))
.build();
- 分页
创建一个分页辅助类:
import org.springframework.data.domain.Page;
import java.util.List;
public class PageHelper<T> {
private long total;
private List<T> list;
private int pageNum;
private int pageSize;
private int pages;
private int previousPageNum;
private int nextPageNum;
private boolean previousPage;
private boolean nextPage;
private int[] navigatePageNums;
public PageHelper(Page<T> page, int pageNum, int pageSize) {
this.list = page.getContent();
this.total = page.getTotalElements();
this.pageNum = pageNum;
this.pageSize = pageSize;
this.pages = page.getTotalPages();
this.previousPage = false;
this.nextPage = false;
int startNum = 1;
int endNum = pages;
int navigateNums = 10; //导航栏显示数字个数
if (pages <= navigateNums) {
} else if ((pageNum + (navigateNums + 1) / 2) > pages) {
startNum = pages - (navigateNums - 1);
endNum = pages;
} else if (pageNum <= (navigateNums + 1) / 2) {
endNum = navigateNums;
} else {
if (navigateNums % 2 == 0) {
startNum = pageNum - navigateNums / 2;
endNum = pageNum + (navigateNums - 1) / 2;
} else {
startNum = pageNum - navigateNums / 2;
endNum = pageNum + navigateNums / 2;
}
}
this.navigatePageNums = new int[endNum - startNum + 1];
for (int i = startNum; i <= endNum; i++) {
this.navigatePageNums[i - startNum] = i;
}
for (int i = 0; i < this.pages; ++i) {
this.navigatePageNums[i] = i + 1;
}
if (this.pageNum > 1) {
this.previousPage = true;
this.previousPageNum = this.pageNum - 1;
}
if (this.pageNum < this.pages) {
this.nextPage = true;
this.nextPageNum = this.pageNum + 1;
}
}
//getter/setter略
}
controller改造后如下:
@RequestMapping("/blogs")
public String query(Model model, Integer pageNum, Integer pageSize) {
if(pageNum == null || pageNum <= 0)
pageNum = 1;
if(pageSize == null || pageSize <= 0)
pageSize = 5;
SearchQuery searchQuery = new NativeSearchQueryBuilder()
.withPageable(new QPageRequest(pageNum - 1, pageSize))
.withQuery(QueryBuilders.matchAllQuery())
.withSort(SortBuilders.fieldSort("date").order(SortOrder.DESC))
.build();
Page<Blog> blogs = elasticsearchTemplate.queryForPage(searchQuery, Blog.class);
model.addAttribute("blogs", blogs.getContent());
model.addAttribute("pageHelper", new PageHelper<>(blogs, pageNum, pageSize));
return "index";
}
创建一个展示层的分页组件,pagenation.html:
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<th:block th:fragment="formBase(pageInfo)">
<input type="hidden" id="pageNum" name="pageNum"/>
<div class="col-sm-6">
<div class="dataTables_length">
<label><select name="pageSize" class="form-inline input-sm" onchange="javascript:page(1);">
<option value="5" th:selected="${pageInfo.pageSize == 5}">5</option>
<option value="10" th:selected="${pageInfo.pageSize == 10}">10</option>
<option value="20" th:selected="${pageInfo.pageSize == 20}">20</option>
<option value="50" th:selected="${pageInfo.pageSize == 50}">50</option>
<option value="100" th:selected="${pageInfo.pageSize == 100}">100</option>
</select> <th:block th:text="'条/页, 共' + ${pageInfo.total} + '条'"></th:block></label></div>
</div>
<div class="col-sm-6">
<div class="dataTables_filter" style="text-align: right">
<ul class="pagination pagination-sm no-margin">
<th:block th:if="${pageInfo.previousPage}">
<li class="paginate_button previous"><a th:href="@{'javascript:page(' + ${pageInfo.previousPageNum} + ');'}"
th:text="Previous"></a></li>
</th:block>
<th:block th:each="nav:${pageInfo.navigatePageNums}">
<li th:class="${pageInfo.pageNum} == ${nav} ? 'paginate_button active' : 'paginate_button'"><a
th:href="@{'javascript:page(' + ${nav} + ');'}" th:text="${nav}">1</a></li>
</th:block>
<th:block th:if="${pageInfo.nextPage}">
<li class="paginate_button next"><a th:href="@{'javascript:page(' + ${pageInfo.nextPageNum} + ');'}"
th:text="Next"></a></li>
</th:block>
</ul>
</div>
</div>
<script type="text/javascript">
function page(pageNum) {
document.getElementById("pageNum").value = pageNum;
document.forms[0].submit();
}
</script>
</th:block>
在列表页引用该组件
<div class="box-footer">
<th:block th:replace="pagenation::formBase(${pageHelper})"></th:block>
</div>
重新运行后在页面底部显示分页栏:
源码:
链接:https://pan.baidu.com/s/1CaQp5LrcWdLp0UXUPrPbKg
提取码:t5qj