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的增删查改已完成................

 

posted @ 2020-05-01 16:40  itch  阅读(4357)  评论(2编辑  收藏  举报