SpringBoot+ES实现增删查改
小广告...:https://www.mvclub.xyz/【个人搭建的一个电影网站】
任务要求
使用logstash将数据导入到ES中,并且实现增删查改和分页查询
要求实现:
1、 功能一:搭建es环境
2、 功能二:将测试数据导入到mysql中
3、 功能三:使用logstash将数据导入到ES中
4、 功能四:SpringBoot整合ES
5、 功能五:增删查改+高亮
6、 功能六:提供restful接口,并且使用postman测试接口
具体实现
功能一:
完成es搭建
https://www.cnblogs.com/IT_CH/p/12779770.html
功能二:
将测试数据导入到mysql中,测试数据是一个xlsx格式的数据
因为关注点不是这一部分,我们就直接使用Navicat直接将数据导入即可
代码完成导入则参考:..............待完成
功能三:
使用logstash将数据导入到ES中
(1)先下载logstash-6.8.7,下载你的ES对应的版本,我使用的是6.8.7
(2)准备.conf脚本文件,对应将里面的一些修改完即可
注意:%{id}:你的表中必须要有这个字段,你的别的字段,相应的更换即可
input { stdin {} jdbc { jdbc_connection_string => "jdbc:mysql://localhost:3306/test1" jdbc_user => "root" jdbc_password => "root" jdbc_driver_library => "G:\repo\mysql\mysql-connector-java\5.1.47\mysql-connector-java-5.1.47.jar" jdbc_driver_class => "com.mysql.jdbc.Driver" jdbc_paging_enabled => "true" jdbc_page_size => "100000" statement => "select * from tb_totalcount" type => "jdbc" } } output { elasticsearch { hosts => "127.0.0.1:9200" index => "test1" document_type => "user" document_id => "%{id}" } stdout { codec => json_lines } }
(3)开始导入数据
(4)查看是否导入成功
功能四:
SpringBoot整合ES
(1)创建SpringBoot项目
(2)在pom.xml中添加一个分页插件的依赖包
<!--分页插件所需依赖包--> <dependency> <groupId>com.github.pagehelper</groupId> <artifactId>pagehelper</artifactId> <version>5.1.4</version> </dependency>
(3)将自动生成的application.properties修改为application.yml,然后编写
一定要注意空格.......
spring: data: elasticsearch: cluster-name: my-application # 集群的名字,一定要和ES配置文件中的一致(elasticsearch.yml) cluster-nodes: 127.0.0.1:9300 # 当前服务器的IP地址 ==> ES有2个端口,Rest端口9200,Java请求端口9300 repositories: enabled: true # 解决跨域问题,在ES的elasticsearch.yml中最后两行 http.cors.enabled: true http.cors.allow-origin: "*"
(4)构建你的项目结构就OK了
注:PageUtil我使用了PageHelper插件,所以就不用添加了
如果你要自己写分页工具类,参考:https://www.cnblogs.com/IT_CH/p/12357660.html
其中有一个分页工具类,粘贴即可用
功能五:
增删查改+高亮查询 -- 就直接贴代码了,注释代码中都已添加
pojo
package com.blb.test1.pojo; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import org.springframework.data.annotation.Id; import org.springframework.data.elasticsearch.annotations.Document; import org.springframework.data.elasticsearch.annotations.Field; import org.springframework.stereotype.Component; import org.springframework.stereotype.Repository; //准备一个实体类,实体类要和你的索引库保持一致 @Data @NoArgsConstructor @AllArgsConstructor /** * Doucment注解 * indexName:索引库的名称 * type:文档的类型 * createIndex:是否创建索引 * 如果要查询的数据是中文的话,一般都需要配置中文分词器,中文分词器有2种 * ik_smart * ik_max_word */ @Document(indexName = "test1",type = "user",createIndex = false) //@Repository public class User { @Id private long id; private String county_name; private String county_code; private String phone_id; private String user_type; private String brand; private String phone_type; private String is4G; private String conty_name; private String ishigh; private String user_id; private String total; private String range4G; @Field(value = "ik_max_word") private String classify; private String totals2G; private String totals3G; private String totals4G; private String lac_id; private String ccell_id; private String total_first; private String total_first_2G; private String total_first_3G; private String total_first_4G; private String total_sec_lacid; private String total_sec_cellid; private String total_sec; private String total_sec_2G; private String total_sec_3G; private String total_sec_4G; private String total_three_lacid; private String total_three_cellid; private String total_three; private String total_three_2G; private String total_three_3G; private String total_three_4G; }
dao
package com.blb.test1.dao; import com.blb.test1.pojo.User; import org.springframework.data.elasticsearch.repository.ElasticsearchRepository; //只要继承了ElasticsearchRepository该类,那么该类就具有了增删查改的方法 //<User,Long>:第一个参数表示为哪个类生成方法,第二个参数表示我们的主键类型 public interface UserDao extends ElasticsearchRepository<User,Long> { }
service
package com.blb.test1.service; import com.blb.test1.pojo.User; import com.github.pagehelper.PageInfo; import java.util.List; public interface UserService { //增加 boolean insertUser(User user); //删除 boolean RemoveUser(long id); //查找--单条数据查询 User queryById(long id); //条件查询加分页 List<User> queryByPage(String keywords, int pageNow, int pageSize); //查询条件+高亮显示 PageInfo queryByHighLight(String keywords, int pageNow, int pageSize); //修改 boolean updateUser(User user); }
package com.blb.test1.service.impl; import com.blb.test1.dao.UserDao; import com.blb.test1.pojo.User; import com.blb.test1.service.UserService; import com.github.pagehelper.PageHelper; import com.github.pagehelper.PageInfo; import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.index.query.BoolQueryBuilder; import org.elasticsearch.index.query.MatchAllQueryBuilder; import org.elasticsearch.index.query.QueryBuilder; import org.elasticsearch.index.query.QueryBuilders; import org.elasticsearch.search.SearchHit; import org.elasticsearch.search.SearchHits; import org.elasticsearch.search.builder.SearchSourceBuilder; import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder; import org.elasticsearch.search.fetch.subphase.highlight.HighlightField; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; import org.springframework.data.elasticsearch.core.ElasticsearchTemplate; import org.springframework.data.elasticsearch.core.SearchResultMapper; import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage; import org.springframework.data.elasticsearch.core.aggregation.impl.AggregatedPageImpl; import org.springframework.data.elasticsearch.core.query.NativeSearchQuery; import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder; import org.springframework.stereotype.Service; import javax.swing.text.Highlighter; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Optional; @Service public class UserServiceImpl implements UserService { @Autowired private UserDao userDao; @Autowired private ElasticsearchTemplate elasticsearchTemplate; @Override public boolean insertUser(User user) { return userDao.save(user).getId() > 0; } @Override public boolean RemoveUser(long id) { userDao.deleteById(id); return true; } @Override public User queryById(long id) { return userDao.findById(id).get(); } //关键字查询,关键字匹配classify字段 @Override public List<User> queryByPage(String keywords, int pageNow, int pageSize) { List<User> users = new ArrayList<>(); //先构建查询条件 BoolQueryBuilder query = QueryBuilders.boolQuery(); /** * should 或;must 并;not must 非 * matchQuery:字段匹配 */ query.should(QueryBuilders.matchQuery("classify",keywords)); //分页查询 PageRequest pageRequest = PageRequest.of(pageNow, pageSize,Sort.by(Sort.Order.asc("id"))); // PageRequest pageRequest = PageRequest.of(pageNow, pageSize); //开始查询 Iterable<User> search = userDao.search(query, pageRequest); Iterator<User> userIterator = search.iterator(); while (userIterator.hasNext()){ users.add(userIterator.next()); } return users; } //高亮查询+分页 @Override public PageInfo queryByHighLight(String keywords, int pageNow, int pageSize) { //设置分页的数据 PageHelper.startPage(pageNow,pageSize); //构建查询条件 BoolQueryBuilder query = QueryBuilders.boolQuery(); //如果还有别的要查询的关键字,就继续.should(QueryBuilders.matchQuery("你要查询的字段",keywords)) query.should(QueryBuilders.matchQuery("classify",keywords)); //分页 PageRequest pageRequest = PageRequest.of(pageNow, pageSize,Sort.by(Sort.Order.asc("id"))); //高亮设置 HighlightBuilder highlightBuilder = new HighlightBuilder(); highlightBuilder.preTags("<em>") .postTags("</em>") .field("classify"); //NativeSearchQueryBuilder 将多个条件组合在一起 NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder(); //组合高亮显示 nativeSearchQueryBuilder.withHighlightBuilder(highlightBuilder); //组合分页 nativeSearchQueryBuilder.withPageable(pageRequest); //组合查询条件 nativeSearchQueryBuilder.withQuery(query); //也可以组合排序条件 // nativeSearchQueryBuilder.withSort() //将查询结果和我们的高亮结合起来 //将数据查出来之后要转化成什么类型的,最后一个参数就是用啦处理高亮的 AggregatedPage<User> userList = elasticsearchTemplate.queryForPage(nativeSearchQueryBuilder.build(), User.class, new SearchResultMapper() { //将查询的结果和我们要设置的高亮样式结合起来 @Override public <T> AggregatedPage<T> mapResults(SearchResponse searchResponse, Class<T> aClass, Pageable pageable) { //先将数据用一个容器存放起来 ArrayList<User> arrayList = new ArrayList<>(); //我们查询的结果都是放在searchResponse中的 //我们现在就是要把我们想要的内容从searchResponse中获取到 SearchHits hits = searchResponse.getHits(); //如果getTotalHits是0,则表示查询不到数据 if (hits.getTotalHits() <= 0) { return null; } //从里面获取一条一条的数据 for (SearchHit hit : hits) { User user = new User(); String classify = (String) hit.getSourceAsMap().get("classify"); //拿到数据之后,我们还要获取到某个字段的高亮特征,高亮特征要和当前的数据做一个替换 HighlightField highlightField = hit.getHighlightFields().get("classify"); if (highlightField != null) { user.setClassify(highlightField.fragments()[0].toString()); } user.setClassify(classify); arrayList.add(user); } return new AggregatedPageImpl(arrayList); } @Override public <T> T mapSearchHit(SearchHit searchHit, Class<T> aClass) { return null; } }); //使用pageInfo对数据进行封装 PageInfo<User> pageInfo = new PageInfo<User>(userList.toList()); return pageInfo; } @Override public boolean updateUser(User user) { return userDao.save(user).getId()>0; } }
controller
package com.blb.test1.controller; import com.blb.test1.pojo.User; import com.blb.test1.service.UserService; import com.github.pagehelper.PageInfo; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import java.io.UnsupportedEncodingException; import java.util.HashMap; import java.util.List; import java.util.Map; @RestController @RequestMapping(value = "/user") @CrossOrigin("*") public class UserController { @Autowired private UserService userService; @PostMapping("/insert") public Map insert(@RequestBody User user){ HashMap map = new HashMap(); userService.insertUser(user); map.put("msg","插入成功"); map.put("status",true); map.put("code",0); return map; } @GetMapping("/delete/{id}") public Map delete(@PathVariable("id") int id){ HashMap map = new HashMap(); userService.RemoveUser(id); map.put("msg","删除成功"); map.put("status",true); map.put("code",0); return map; } @GetMapping("/select/{id}") public Map queryById(@PathVariable("id") int id){ HashMap map = new HashMap(); User user = userService.queryById(id); map.put("status",true); map.put("data",user); map.put("msg","查询成功"); map.put("code",0); return map; } @PostMapping("/search/{pageNow}/{pageSize}") public Map queryByKey(@RequestBody String keyword, @PathVariable("pageNow") int pageNow,@PathVariable("pageSize") int pageSize) throws UnsupportedEncodingException { //前台post传输的数据是中文的数据,通过debug方式看到它是一个编码后的一个值 //所以会出现匹配不到数据,所以我们要先将传过来的数据进行解码,不然就匹配不到 //如果你没匹配到,用debug模式查看是不是这个原因...... String json=java.net.URLDecoder.decode(keyword,"UTF-8"); System.out.print(json); HashMap map = new HashMap(); List<User> list = userService.queryByPage(json, pageNow, pageSize); map.put("msg","查询成功"); map.put("data",list); map.put("code",0); map.put("count",list.size()); return map; } @PostMapping("/searchHighLight/{pageNow}/{pageSize}") public Map queryByPageForHighLight(@RequestBody String keyword, @PathVariable("pageNow") int pageNow,@PathVariable("pageSize") int pageSize) throws UnsupportedEncodingException { //前台post传输的数据是中文的数据,通过debug方式看到它是一个编码后的一个值 //所以会出现匹配不到数据,所以我们要先将传过来的数据进行解码,不然就匹配不到 //如果你没匹配到,用debug模式查看是不是这个原因...... String json=java.net.URLDecoder.decode(keyword,"UTF-8"); System.out.print(json); HashMap map = new HashMap(); PageInfo pageInfo = userService.queryByHighLight(json, pageNow, pageSize); map.put("msg","查询成功"); map.put("data",pageInfo.getList()); map.put("code",0); map.put("count",pageInfo.getTotal()); return map; } }
启动类
@EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class})
因为我的启动有问题,如果不加该注解我的就启动不起来
自己视情况定。
package com.blb.test1; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; /** * https://blog.csdn.net/wcc27857285/article/details/90679424 */ @SpringBootApplication @EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class}) public class Test1Application { public static void main(String[] args) { SpringApplication.run(Test1Application.class, args); } }
功能六:
提供restful接口,并且使用postman进行测试
由于懒,所以就没测试添加和修改操作了,自己可以测试一下.......
OK...SpringBoot +ES的增删查改已完成................