一、PagerHelper插件的使用
(一)创建一张新闻表和对应java的pojo类
1、创建t_newa表
CREATE TABLE `t_news` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`news_id` char(255) NOT NULL,
`author_id` int(11) NOT NULL,
`news_title` varchar(255) NOT NULL,
`news_content` text NOT NULL,
`news_imgs` text,
`create_time` varchar(255) NOT NULL DEFAULT '0000-00-00 00:00:00',
`update_time` timestamp NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `newsId` (`news_id`)
)
2、 新闻表所对应的pojo类
import lombok.Data;
@Data
public class NewsPO {
private int id;
private String newsId;
private int authorId;
private String newsTitle;
private String newsContent;
private String newsImgs;
private long createTime;、
}
3、 分页查询数据包装类
public class BasePage<T> {
//当前页码
private Integer pageNum=1;
//总页数
private Integer pageTotal;
//每页的条数
private Integer pageSize=10;
//总条数
private Integer totalSize;
//起始索引
private Integer startIndex;
//是否有更多
private boolean isMore;
private List<T> list;
public BasePage(){
super();
}
public BasePage(Integer totalSize,Integer pageNum,Integer pageSize){
this.pageNum=pageNum;
this.pageSize=pageSize;
this.totalSize=totalSize;
this.pageTotal=(this.totalSize+this.pageSize-1)/this.pageSize;
this.startIndex=(this.pageNum-1)*pageSize;
this.isMore=this.pageNum<this.pageTotal;
}
}
(二)SpringBoot集成PagerHelper插件
1、pom.xml文件添加pagerhelper的坐标依赖
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.2.3</version>
</dependency>
稳妥起见,pagerhelper的版本使用1.2.3
2、在SpringBoot项目的启动入口加入pagerhelper的注入配置
@SpringBootApplication(scanBasePackages = {"cn.fcw.bb.webapply"})
@MapperScan(basePackages = {"cn.fcw.bb.webapply.mapper"})
public class WebApplyApplication {
public static void main(String[] args) {
SpringApplication.run(WebApplyApplication.class, args);
}
/**
* https://github.com/pagehelper/Mybatis-PageHelper
* 注入PagerHelper的配置
*/
@Bean
public PageHelper pageHelper(){
PageHelper pageHelper=new PageHelper();
Properties properties=new Properties();
properties.setProperty("offsetAsPageNum","true");
properties.setProperty("rowBoundsWithCount","true");
properties.setProperty("reasonable","true");
properties.setProperty("dialect","mysql");
pageHelper.setProperties(properties);
return pageHelper;
}
}
3、在application.properties中加入pagerhelper的启动配置
#分页插件
pagehelper.helper-dialect=mysql
pagehelper.params=count=countSql
pagehelper.reasonable=true
pagehelper.support-methods-arguments=true
4、创建mapper接口和mapper.xml文件
public interface INewsMapper {
List<NewsPO> findAllNews();
Integer getTotalNum();
}
实现mapper接口的xml文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.fcw.bb.webapply.mapper.INewsMapper">
<resultMap id="findNewsRes" type="cn.fcw.bb.webapply.model.NewsPO" autoMapping="true">
<id column="id" property="id"/>
<result column="news_id" property="newsId"/>
<result column="news_title" property="newsTitle"/>
<result column="news_content" property="newsContent"/>
<result column="news_imgs" property="newsImgs"/>
<result column="author_id" property="authorId"/>
<result column="create_time" property="createTime"/>
</resultMap>
<select id="getTotalNum" resultType="java.lang.Integer">
SELECT COUNT(*) FROM t_news;
</select>
<select id="findAllNews" resultMap="findNewsRes">
SELECT * FROM t_news
</select>
</mapper>
5、servie的业务逻辑
public interface INewsService {
@Transactional
BasePage<NewsPO> findAllNews(Integer pageNum, Integer pageSize);
}
<!------------------------------------------------------------------------>
@Service
public class NewsServiceImpl implements INewsService {
@Autowired
private INewsMapper newsMapper;
@Override
public BasePage<NewsPO> findAllNews(Integer pageNum, Integer pageSize) {
int total=newsMapper.getTotalNum();
PageHelper.startPage(pageNum,pageSize);
List<NewsPO> list=newsMapper.findAllNews();
BasePage<NewsPO> basePage=new BasePage<>(total,pageNum,pageSize);
basePage.setList(list);
return basePage;
}
}
6、controller代码
@RestController
@RequestMapping("/news")
public class NewsController {
@Autowired
private INewsService newsService;
@RequestMapping(value = "/getNewsList",method = {RequestMethod.GET})
public BasePage<NewsPO> getNewsList(@Param(value = "pageNum")Integer pageNum, @Param(value ="pageSize")Integer pageSize){
if(pageNum==null) pageNum=1;
if(pageSize==null) pageSize=40;
BasePage basePage=newsService.findAllNews(pageNum,pageSize);
return basePage;
}
}
7、管理后台测试页面
<!DOCTYPE HTML>
<html>
<head>
<meta charset="UTF-8">
<title>新闻列表</title>
<link rel="stylesheet" href="../../js/easyui/themes/icon.css"/>
<link rel="stylesheet" href="../../js/easyui/themes/default/easyui.css"/>
<link rel="stylesheet" href="../../css/bootstrap.css"/>
<link rel="stylesheet" href="../../css/bootstrap-theme.css"/>
<script type="text/javascript" src="../../js/jquery-3.3.1.min.js"></script>
<script type="text/javascript" src="../../js/bootstrap.js"></script>
<style>
html, body {
padding: 0;
margin: 0;
height: 100%;
overflow: hidden;
}
th{
align-content: center;
}
td{
height: 100px;
align-content: center;
}
</style>
<script>
var index=0;
$(function () {
$.get("/news/getNewsList", function (data) {
setPage(data.pageTotal);
setTable(data.list);
});
});
function httpGetData (pageNum) {
var url="/news/getNewsList?pageNum="+pageNum+"&pageSize=40";
console.log("请求路劲="+url);
$.get(url, function (data) {
index=data.startIndex;
setTable(data.list);
});
}
//表格填充数据
function setTable(data) {
var $table=$("#tt_body");
$table.empty();
for(var i=0,len=data.length;i<len;i++){
index++;
var obj=data[i];
var $tr=$("<tr></tr>");
var $tdnewsNo=$("<td style='width: 5%'>"+index+"</td>");
var $tdnewsTitle=$("<td style='width: 10%'>"+obj.newsTitle+"</td>");
var $tdnewsContent=$("<td style='width:80%;padding: 5px'>"+obj.newsContent+"</td>");
var $tdnewsIms=$("<td><img style='width: 100px;height: 100px' src="+obj.newsImgs +"></td>");
var $tdnewsId=$("<td style='display: none'>"+obj.newsId+"</td>");
$tr.append($tdnewsNo);
$tr.append($tdnewsId);
$tr.append($tdnewsTitle);
$tr.append($tdnewsContent);
$tr.append($tdnewsIms);
$table.append($tr);
}
}
//设置分页控件数据
function setPage(data) {
var $ul=$(".pagination");
for(var i=1;i<=data;i++){
var $li=$("<li></li>");
//var $a=$("<a href=\"javascript void(0)\">"+i+"</a>");
var $a=$("<a href='#'>"+i+"</a>");
$li.append($a);
$ul.append($li);
$($li).click(function () {
var index= $(this).find("a").html();
httpGetData(parseInt(index));
});
}
}
</script>
</head>
<body>
<div style="width:100%;height:5%">
<div class="input-group" style="width:50%;margin-left: 100px;margin-right: 100;margin-top: 20px">
<input type="text" class="form-control" placeholder="请输入搜索关键字">
<span class="input-group-btn">
<button class="btn btn-default" type="button">搜索</button>
</span>
</div>
</div>
<div style="width: 100%;height: 80%;padding: 20px;">
<div style="overflow: auto;height: 100%">
<table class="table table-bordered">
<thead>
<tr>
<th>新闻编号</th>
<th>新闻标题</th>
<th>新闻内容</th>
<th>新闻图片</th>
<th style="display: none"></th>
</tr>
</thead>
<tbody id="tt_body"></tbody>
</table>
</div>
</div>
<div style="width: 100%;height: 15%;padding-left: 20px;padding-right: 20px;margin-bottom: 20px">
<div style="width=100%;height=100%;overflow-x: scroll;overflow-y:hidden;">
<ul class="pagination">
</ul>
</div>
</div>
</body>
</html>
二、Elasticsearch全文搜索
ElasticSearch是一个基于Lucene的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口。Elasticsearch是用Java开发的,并作为Apache许可条款下的开放源码发布,是当前流行的企业级搜索引擎。设计用于云计算中,能够达到实时搜索,稳定,可靠,快速,安装使用方便。
1、环境搭建,centos安装 ElasticSearch
(1)官网下载es的tar压缩文件文件(https://www.elastic.co/downloads/elasticsearch),上传至centos服务器目录
执行解压命令:tar -xvzf elasticsearch-6.4.0.tar.gz
(2)修改配置文件:
进入es的配置文件: cd elasticsearch/config
修改es的host和端口:vi elasticsearch.yml
(3)启动ES服务(如果启动报错可以参考这篇博客https://www.cnblogs.com/xxoome/p/6663993.html)
启动命令:
启动成功的信息:
浏览器测试:
2、后台springboot集成Elasticsearch
(1)pom.xml文件加入Elasticsearch的maven坐标
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
(2)application.properties添加es的配置
#客户端访问es服务必须使用9300端口
spring.data.elasticsearch.cluster-nodes=192.168.137.133:9300
(3) java后台代码
需求:把新闻表中的记录存放到es上,然后根据标题关键字或内容关键字查询新闻
1>创建新闻的文档类(用于存储到es数据库上)
/**
* 新闻的es文档类
* @Document 文档类注解
* indexName 文档索引
* type 文档类型
*/
@Document(indexName = "newsdb",type = "news")
public class EsNews implements Serializable {
@Id //标示主键
private String id; //id必须是字符串
private String newsTitle;
private String newsContent;
private String newsImgs;
protected EsNews(){ } //JPA 空参构造方法 编写规范
public EsNews(String id,String newsTitle,String newsContent,String newsImgs){
this.id=id;
this.newsTitle=newsTitle;
this.newsContent=newsContent;
this.newsImgs=newsImgs;
}
}
2>创建新闻文档的资源库
public interface EsNewsRepository extends ElasticsearchRepository<EsNews,String> {
//按照含有标题关键字或者内容关键字搜索新闻
List<EsNews> findDistinctEsNewsByNewsTitleContainingOrNewsContentContaining(String title, String content);
}
3>controller层的业务代码,查询分页数据的时候讲分页数据存入es中:
@RestController
@RequestMapping("/news")
public class NewsController {
@Autowired
private INewsService newsService;
@Autowired
private EsNewsRepository esNewsRepository;
@RequestMapping("/getNewsCommentDetailById")
public BaseBean<NewsCommentDetailPO> getNewsCommentDetailById(){
return newsService.findNewsDetailById(1);
}
@RequestMapping(value = "/getNewsList",method = {RequestMethod.GET})
public BasePage<NewsPO> getNewsList(@Param(value = "pageNum")Integer pageNum, @Param(value ="pageSize")Integer pageSize){
if(pageNum==null) pageNum=1;
if(pageSize==null) pageSize=40;
BasePage basePage=newsService.findAllNews(pageNum,pageSize);
saveNews2ES(basePage);//调用es存储方法
return basePage;
}
/**
* 将分页查出来的新闻数据添加到es中
*/
private void saveNews2ES(BasePage basePage){
List<NewsPO> list=basePage.getList();
esNewsRepository.deleteAll();//先清空es存储
EsNews news;
for (NewsPO newsPO : list) {
news=new EsNews(newsPO.getNewsId(),newsPO.getNewsTitle(),newsPO.getNewsContent(),newsPO.getNewsImgs());
esNewsRepository.save(news);
}
}
/**
*通过关键字搜索新闻
* @param title
* @param content
* @return
*/
@RequestMapping("/searchNewsList")
public List<EsNews> searchNews(@Param(value = "title")String title,@Param(value = "content")String content) {
return esNewsRepository.findDistinctEsNewsByNewsTitleContainingOrNewsContentContaining(title,content);
}
}
4>后台页面代码:
<!DOCTYPE HTML>
<html>
<head>
<meta charset="UTF-8">
<title>新闻列表</title>
<link rel="stylesheet" href="../../js/easyui/themes/icon.css"/>
<link rel="stylesheet" href="../../js/easyui/themes/default/easyui.css"/>
<link rel="stylesheet" href="../../css/bootstrap.css"/>
<link rel="stylesheet" href="../../css/bootstrap-theme.css"/>
<script type="text/javascript" src="../../js/jquery-3.3.1.min.js"></script>
<script type="text/javascript" src="../../js/bootstrap.js"></script>
<style>
html, body {
padding: 0;
margin: 0;
height: 100%;
overflow: hidden;
}
th{
align-content: center;
}
td{
height: 100px;
align-content: center;
}
</style>
<script>
var index=0;
$(function () {
$.get("/news/getNewsList", function (data) {
setPage(data.pageTotal);
setTable(data.list);
});
});
//获取分页数据
function httpGetData (pageNum) {
var url="/news/getNewsList?pageNum="+pageNum+"&pageSize=40";
console.log("请求路劲="+url);
$.get(url, function (data) {
index=data.startIndex;
setTable(data.list,true);
});
}
/**
* flag true表示数据库查询 、false 表示es搜索
*/
function setTable(data,flag) {
var $table=$("#tt_body");
$table.empty();
for(var i=0,len=data.length;i<len;i++){
index++;
var obj=data[i];
var $tr=$("<tr></tr>");
var $tdnewsNo=$("<td style='width: 5%'>"+index+"</td>");
var $tdnewsTitle=$("<td style='width: 10%'>"+obj.newsTitle+"</td>");
var $tdnewsContent=$("<td style='width:80%;padding: 5px'>"+obj.newsContent+"</td>");
var $tdnewsIms=$("<td><img style='width: 100px;height: 100px' src="+obj.newsImgs +"></td>");
var $tdnewsId;
if (flag)
$tdnewsId=$("<td style='display: none'>"+obj.newsId+"</td>");
else
$tdnewsId=$("<td style='display: none'>"+obj.id+"</td>");
$tr.append($tdnewsNo);
$tr.append($tdnewsId);
$tr.append($tdnewsTitle);
$tr.append($tdnewsContent);
$tr.append($tdnewsIms);
$table.append($tr);
}
}
function setPage(data) {
var $ul=$(".pagination");
for(var i=1;i<=data;i++){
var $li=$("<li></li>");
//var $a=$("<a href=\"javascript void(0)\">"+i+"</a>");
var $a=$("<a href='#'>"+i+"</a>");
$li.append($a);
$ul.append($li);
$($li).click(function () {
var index= $(this).find("a").html();
httpGetData(parseInt(index));
});
}
}
/**
* 新闻搜索方法
*/
function search() {
var s=$(".form-control");
var key=s.val();
if (key===""||key==null){
alert("请输入标题或内容关键字");
} else {
var url="/news/searchNewsList?title="+key+"&content="+key;
$.get(url,function (data) {
index=0;
setTable(data,false);
});
}
}
</script>
</head>
<body>
<div style="width:100%;height:5%">
<div class="input-group" style="width:50%;margin-left: 100px;margin-right: 100;margin-top: 20px">
<input type="text" class="form-control" placeholder="请输入搜索关键字">
<span class="input-group-btn">
<button class="btn btn-default" type="button" onclick="search()">搜索</button>
</span>
</div>
</div>
<div style="width: 100%;height: 80%;padding: 20px;">
<div style="overflow: auto;height: 100%">
<table class="table table-bordered">
<thead>
<tr>
<th>新闻编号</th>
<th>新闻标题</th>
<th>新闻内容</th>
<th>新闻图片</th>
<th style="display: none"></th>
</tr>
</thead>
<tbody id="tt_body"></tbody>
</table>
</div>
</div>
<div style="width: 100%;height: 15%;padding-left: 20px;padding-right: 20px;margin-bottom: 20px">
<div style="width=100%;height=100%;overflow-x: scroll;overflow-y:hidden;">
<ul class="pagination">
</ul>
</div>
</div>
</body>
</html>
运行效果: