IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> 基于spring-boot-starter-data-elasticsearch实现的ES API插件 -> 正文阅读

[Java知识库]基于spring-boot-starter-data-elasticsearch实现的ES API插件

目录

1.背景

2.实现方案

2.1代码目录

2.2实际代码

3.如何调用


1.背景

在使用spring-boot-starter-data-elasticsearch过程中,基本可以满足业务的大部分需求,但是会发现几个问题,

1.多个业务线都需要使用ES组件的时候,都要重复的引入初始化文件,这样代码重复率很高

2.不同索引都要创建自定义的Repository,但是自定义Repository中不需要任何自定义的业务逻辑,导致代码量无故增加

3.spring-boot-starter-data-elasticsearch提供多种api,容易导致开发乱用,不便于统一

为了解决上面的问题,我重新写了一个ES API,废话不多说,直接看代码。

2.实现方案

2.1代码目录

2.2实际代码

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
 ? ? ? ? xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 ? ? ? ? xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 ? ?<groupId>com.demo</groupId>
 ? ?<modelVersion>4.0.0</modelVersion>
 ? ?<artifactId>demo-elasticsearch-components</artifactId>
 ? ?<version>1.0.0-SNAPSHOT</version>
    <packaging>pom</packaging>
?
 ? ?<dependencies>
 ? ? ? ?<dependency>
 ? ? ? ? ? ?<groupId>org.projectlombok</groupId>
 ? ? ? ? ? ?<artifactId>lombok</artifactId>
 ? ? ? ? ? ?<version>1.18.12</version>
 ? ? ? ?</dependency>
?
 ? ? ? ?<dependency>
 ? ? ? ? ? ?<groupId>org.springframework.boot</groupId>
 ? ? ? ? ? ?<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
 ? ? ? ? ? ?<version>2.2.6.RELEASE</version>
 ? ? ? ?</dependency>
 ? ?</dependencies>
?
</project>
EsConfiguration.java
package com.demo.elasticsearch.config;
?
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpHost;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestClientBuilder;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
?
@Slf4j
@Configuration
@ComponentScan({"com.demo.elasticsearch.service"})
public class EsConfiguration implements FactoryBean<RestHighLevelClient>, InitializingBean, DisposableBean {
?
 ? ?@Value("${spring.data.elasticsearch.host}")
 ? ?private String host;
 ? ?@Value("${spring.data.elasticsearch.port}")
 ? ?private int port;
 ? ?@Value("${spring.data.elasticsearch.username}")
 ? ?private String username;
 ? ?@Value("${spring.data.elasticsearch.password}")
 ? ?private String password;
 ? ?@Value("${spring.data.elasticsearch.scheme:http}")
 ? ?private String scheme;
?
 ? ?private RestHighLevelClient restHighLevelClient;
?
 ? ?@Override
 ? ?public RestHighLevelClient getObject() {
 ? ? ? ?return restHighLevelClient;
 ?  }
?
 ? ?@Override
 ? ?public Class<RestHighLevelClient> getObjectType() {
 ? ? ? ?return RestHighLevelClient.class;
 ?  }
?
 ? ?@Override
 ? ?public boolean isSingleton() {
 ? ? ? ?return false;
 ?  }
?
 ? ?@Override
 ? ?public void afterPropertiesSet() {
 ? ? ? ?buildClient();
 ?  }
?
 ? ?protected void buildClient() {
 ? ? ? ?final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
 ? ? ? ?credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(username, password));
 ? ? ? ?RestClientBuilder builder = RestClient.builder(new HttpHost(host, port,scheme))
 ? ? ? ? ? ? ?  .setHttpClientConfigCallback(httpClientBuilder -> httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider));
 ? ? ? ?restHighLevelClient = new RestHighLevelClient(builder);
 ?  }
?
 ? ?@Override
 ? ?public void destroy() {
 ? ? ? ?try {
 ? ? ? ? ? ?log.info("Closing elasticSearch client");
 ? ? ? ? ? ?if (restHighLevelClient != null) {
 ? ? ? ? ? ? ? ?restHighLevelClient.close();
 ? ? ? ? ?  }
 ? ? ?  } catch (final Exception e) {
 ? ? ? ? ? ?log.error("Error closing ElasticSearch client: ", e);
 ? ? ?  }
 ?  }
?
}

上面的@Value中的配置,来源于引入该api的项目配置yml或properties文件。

EsService.java

package com.demo.elasticsearch.service;
?
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.index.query.QueryBuilder;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.elasticsearch.core.query.SearchQuery;
import org.springframework.data.elasticsearch.core.query.UpdateQuery;
?
import java.util.Optional;
?
public interface EsService {
?
 ? ?<T, S extends T> S save(S entity);
?
 ? ?<T, S extends T> Iterable<S> saveAll(Iterable<S> var1);
?
 ? ?<T, ID> Optional<T> findById(ID var1, Class<T> clazz);
?
 ? ?<T, ID> Iterable<T> findAllById(Iterable<ID> var1, Class<T> clazz);
?
 ? ?<T, ID> void deleteById(ID var1, Class<T> clazz);
?
 ? ?<T, ID> void deleteAllById(Iterable<ID> var1, Class<T> clazz);
?
 ? ?<T> Iterable<T> search(QueryBuilder var1, Class<T> clazz);
?
 ? ?<T> Page<T> search(QueryBuilder var1, Pageable var2, Class<T> clazz);
?
 ? ?<T> Page<T> search(SearchQuery var1, Class<T> clazz);
?
 ? ?<T> long count(SearchQuery var1, Class<T> clazz);
?
 ? ?UpdateResponse update(UpdateQuery query);
}
?
EsServiceImpl.java
package com.demo.elasticsearch.service.impl;
?
import com.demo.elasticsearch.service.EsService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.index.query.QueryBuilder;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.query.*;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
?
import java.util.*;
?
@Slf4j
@Service
@AllArgsConstructor
public class EsServiceImpl implements EsService {
?
 ? ?private final ElasticsearchRestTemplate elasticsearchRestTemplate;
?
 ? ?@Override
 ? ?public <T, S extends T> S save(S entity) {
 ? ? ? ?Assert.notNull(entity, "Cannot save 'null' entity.");
 ? ? ? ?elasticsearchRestTemplate.index(createIndexQuery(entity));
 ? ? ? ?elasticsearchRestTemplate.refresh(entity.getClass());
 ? ? ? ?return entity;
 ?  }
?
 ? ?@Override
 ? ?public <T, S extends T> Iterable<S> saveAll(Iterable<S> entities) {
 ? ? ? ?Assert.notNull(entities, "Cannot insert 'null' as a List.");
 ? ? ? ?List<IndexQuery> queries = new ArrayList();
 ? ? ? ?Iterator var3 = entities.iterator();
?
 ? ? ? ?S s = null;
 ? ? ? ?while(var3.hasNext()) {
 ? ? ? ? ? ?s = (S) var3.next();
 ? ? ? ? ? ?queries.add(createIndexQuery(s));
 ? ? ?  }
 ? ? ? ?elasticsearchRestTemplate.bulkIndex(queries);
 ? ? ? ?if(s!= null){
 ? ? ? ? ? ?elasticsearchRestTemplate.refresh(s.getClass());
 ? ? ?  }
 ? ? ? ?return entities;
 ?  }
?
 ? ?@Override
 ? ?public <T, ID> Optional<T> findById(ID id, Class<T> clazz) {
 ? ? ? ?GetQuery query = new GetQuery();
 ? ? ? ?query.setId(stringIdRepresentation(id));
 ? ? ? ?return Optional.ofNullable(elasticsearchRestTemplate.queryForObject(query, clazz));
 ?  }
?
 ? ?@Override
 ? ?public <T, ID> Iterable<T> findAllById(Iterable<ID> ids, Class<T> clazz) {
 ? ? ? ?Assert.notNull(ids, "ids can't be null.");
 ? ? ? ?SearchQuery query = (new NativeSearchQueryBuilder()).withIds(this.stringIdsRepresentation(ids)).build();
 ? ? ? ?return elasticsearchRestTemplate.multiGet(query, clazz);
 ?  }
?
 ? ?@Override
 ? ?public <T, ID> void deleteById(ID id, Class<T> clazz) {
 ? ? ? ?Assert.notNull(id, "Cannot delete entity with id 'null'.");
 ? ? ? ?elasticsearchRestTemplate.delete(clazz, stringIdRepresentation(id));
 ? ? ? ?elasticsearchRestTemplate.refresh(clazz);
 ?  }
?
 ? ?@Override
 ? ?public <T, ID> void deleteAllById(Iterable<ID> ids, Class<T> clazz) {
 ? ? ? ?Assert.notNull(ids, "Cannot delete 'null' list.");
 ? ? ? ?Iterator var2 = ids.iterator();
?
 ? ? ? ?while(var2.hasNext()) {
 ? ? ? ? ? ?T id = (T) var2.next();
 ? ? ? ? ? ?deleteById(id, clazz);
 ? ? ?  }
 ?  }
?
 ? ?@Override
 ? ?public <T> Iterable<T> search(QueryBuilder query, Class<T> clazz) {
 ? ? ? ?SearchQuery searchQuery = (new NativeSearchQueryBuilder()).withQuery(query).build();
 ? ? ? ?int count = (int)elasticsearchRestTemplate.count(searchQuery, clazz);
 ? ? ? ?if (count == 0) {
 ? ? ? ? ? ?return new PageImpl(Collections.emptyList());
 ? ? ?  } else {
 ? ? ? ? ? ?searchQuery.setPageable(PageRequest.of(0, count));
 ? ? ? ? ? ?return elasticsearchRestTemplate.queryForPage(searchQuery, clazz);
 ? ? ?  }
 ?  }
?
 ? ?@Override
 ? ?public <T> Page<T> search(QueryBuilder query, Pageable pageable, Class<T> clazz) {
 ? ? ? ?SearchQuery searchQuery = (new NativeSearchQueryBuilder()).withQuery(query).withPageable(pageable).build();
 ? ? ? ?return elasticsearchRestTemplate.queryForPage(searchQuery, clazz);
 ?  }
?
 ? ?@Override
 ? ?public <T> Page<T> search(SearchQuery query, Class<T> clazz) {
 ? ? ? ?return elasticsearchRestTemplate.queryForPage(query, clazz);
 ?  }
?
 ? ?@Override
 ? ?public <T> long count(SearchQuery query, Class<T> clazz) {
 ? ? ? ?return elasticsearchRestTemplate.count(query, clazz);
 ?  }
?
 ? ?@Override
 ? ?public UpdateResponse update(UpdateQuery query) {
 ? ? ? ?return elasticsearchRestTemplate.update(query);
 ?  }
?
 ? ?private <T> IndexQuery createIndexQuery(T entity) {
 ? ? ? ?IndexQuery query = new IndexQuery();
 ? ? ? ?query.setObject(entity);
 ? ? ? ?return query;
 ?  }
?
 ? ?private <ID> String stringIdRepresentation(ID id) {
 ? ? ? ?return Objects.toString(id, (String)null);
 ?  }
?
 ? ?private <ID> List<String> stringIdsRepresentation(Iterable<ID> ids) {
 ? ? ? ?Assert.notNull(ids, "ids can't be null.");
 ? ? ? ?List<String> stringIds = new ArrayList();
 ? ? ? ?Iterator var3 = ids.iterator();
?
 ? ? ? ?while(var3.hasNext()) {
 ? ? ? ? ? ?ID id = (ID) var3.next();
 ? ? ? ? ? ?stringIds.add(stringIdRepresentation(id));
 ? ? ?  }
?
 ? ? ? ?return stringIds;
 ?  }
?
}
为了研发同学使用方便,我采用自动装配的方式,把整个api拉起来,即spring.factories,
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.demo.elasticsearch.config.EsConfiguration
至此,代码完毕,是不是很简单。

3.如何调用

把项目deploy到你项目的仓库,然后只需要在项目里引入jar包即可,引入代码如下

<dependency>
 ? ?<groupId>com.demo</groupId>
 ? ?<artifactId>demo-elasticsearch-components</artifactId>
 ? ?<version>1.0.0-SNAPSHOT</version>
</dependency>
调用时,注入EsService的bean即可,伪代码如下,
@Slf4j
@Component
@AllArgsConstructor
public class DemoEsHelper {
?
 ? ?private final EsService esService;
?
 ? ?/**
 ? ? * demo
 ? ? * @param doc
 ? ? */
 ? ?public void test(Document doc){
    //保存
 ? ? ? ?esService.save(doc);
 ? ? ? ?//批量保存
 ? ? ? ?List<Document> documentList = new ArrayList<>();
 ? ? ? ?esService.saveAll(documentList);
 ? ? ? ?//根据ID查询数据
 ? ? ? ?Optional<Document> queryDocument = esService.findById("demo_id", Document.class);
 ? ? ? ?//根据id列表批量查询数据
 ? ? ? ?List<String> ids = new ArrayList<>();
 ? ? ? ?Iterable<Document> queryDocuments = esService.findAllById(ids, Document.class);
 ? ? ? ?//根据id删除某条数据
 ? ? ? ?esService.deleteById("demo_id", ?Document.class);
 ? ? ? ?//根据id列表批量删除数据
 ? ? ? ?esService.deleteAllById(ids, Document.class);
 ? ? ? ?//根据QueryBuilder条件批量查询数据
 ? ? ? ?BoolQueryBuilder queryBuilder = boolQuery();
 ? ? ? ?Iterable<Document> queryDocumentIterable = esService.search(queryBuilder, Document.class);
 ? ? ? ?//根据QueryBuilder条件分页查询数据
 ? ? ? ?Sort sort = Sort.by(new Sort.Order(Sort.Direction.DESC, "createTime"));
 ? ? ? ?Pageable pageable = PageRequest.of(0, 10, sort);
 ? ? ? ?Page<Document> queryDocuments = esService.search(queryBuilder,pageable, Document.class);
 ? ? ? ?//根据SearchQuery条件分页查询数据
 ? ? ? ?Page<Document> queryDocuments2 = esService.search(SearchQuery, Document.class);
 ? ? ? ?//根据SearchQuery条件统计数量
 ? ? ? ?long count = esService.count(SearchQuery, Document.class);
 ? ? ? ?//根据UpdateQuery更新数据
 ? ? ? ?esService.update(updateQuery);
    
  }
}

至此结束。

总结下,本插件主要是在spring-boot-starter-data-elasticsearch技术基础上,自定义开发了统一的接口,为的是解决业务中实际发生的一些问题,提高团队开发效率。注意这个插件需要放到spring boot项目中才能使用。

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-03-30 18:09:58  更:2022-03-30 18:13:29 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 6:17:39-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码