SpringBoot教程(二十八) | SpringBoot集成Elasticsearch(Java High Level Rest Client方式)

news2024/11/28 3:56:22

SpringBoot教程(二十八) | SpringBoot集成Elasticsearch(Java High Level Rest Client方式)

  • 前言
  • 添加maven依赖
  • yml配置
  • ElasticsearchConfig 连接配置类
  • EsUtil 工具类
  • 开始测试

前言

  • 由ES官方提供,代码语法和DSL语法相似(即Json格式的ES操作语法);
  • 用法灵活,可以自由使用;
  • SpringBoot 和 ES 版本的关联性较小;

比较推荐使用这种方式

添加maven依赖

我看网上一般都是用以下这个

<dependency>
     <groupId>org.elasticsearch</groupId>
     <artifactId>elasticsearch</artifactId>
     <version>7.15.2</version>
 </dependency>
 <dependency>
     <groupId>org.elasticsearch.client</groupId>
     <artifactId>elasticsearch-rest-client</artifactId>
     <version>7.15.2</version>
 </dependency>
 <dependency>
     <groupId>org.elasticsearch.client</groupId>
     <artifactId>elasticsearch-rest-high-level-client</artifactId>
     <version>7.15.2</version>
 </dependency>

依赖解释

  • elasticsearch
    Elasticsearch的核心库,只是在客户端应用中与Elasticsearch集群交互,通常不需要直接包含这个依赖

  • elasticsearch-rest-client
    低级别的REST客户端,提供了基础的HTTP请求构建和执行能力,但不包括高级抽象,如索引、搜索等操作的封装

  • elasticsearch-rest-high-level-client
    高级REST客户端,它建立在elasticsearch-rest-client之上,提供了更高级别的抽象,如索引、搜索、更新等操作的封装。这使得与Elasticsearch的交互变得更加简单和直接。

yml配置

# es集群名称
elasticsearch.clusterName=single-node-cluster
#es用户名
elasticsearch.userName=elastic
#es密码
elasticsearch.password=elastic
# es host ip 地址(集群):本次使用的是单机模式
elasticsearch.hosts=127.0.0.1:9200
# es 请求方式
elasticsearch.scheme=http
# es 连接超时时间
elasticsearch.connectTimeOut=1000
# es socket 连接超时时间
elasticsearch.socketTimeOut=30000
# es 请求超时时间
elasticsearch.connectionRequestTimeOut=500
# es 最大连接数
elasticsearch.maxConnectNum=100
# es 每个路由的最大连接数
elasticsearch.maxConnectNumPerRoute=100

ElasticsearchConfig 连接配置类

import lombok.Data;
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.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.ArrayList;
import java.util.List;

/**
 * restHighLevelClient 客户端配置类
 */
@Slf4j
@Data
@Configuration
@ConfigurationProperties(prefix = "elasticsearch")
public class ElasticsearchConfig {

    // es host ip 地址(集群)
    private String hosts;
    // es 用户名
    private String userName;
    // es 密码
    private String password;
    // es 请求方式
    private String scheme;
    // es 集群名称
    private String clusterName;
    // es 连接超时时间
    private int connectTimeOut;
    // es socket 连接超时时间
    private int socketTimeOut;
    // es 请求超时时间
    private int connectionRequestTimeOut;
    // es 最大连接数
    private int maxConnectNum;
    // es 每个路由的最大连接数
    private int maxConnectNumPerRoute;

    /**
     * 如果@Bean没有指定bean的名称,那么这个bean的名称就是方法名
     */
    @Bean(name = "restHighLevelClient")
    public RestHighLevelClient restHighLevelClient() {
        RestHighLevelClient restHighLevelClient = null;
        try {
            // 集群,拆分地址
            List<HttpHost> hostLists = new ArrayList<>();
            String[] hostList = hosts.split(",");
            for (String addr : hostList) {
                String host = addr.split(":")[0];
                String port = addr.split(":")[1];
                hostLists.add(new HttpHost(host, Integer.parseInt(port), scheme));
            }
            // 转换成 HttpHost 数组
            HttpHost[] httpHost = hostLists.toArray(new HttpHost[]{});
            // 构建连接对象
            RestClientBuilder builder = RestClient.builder(httpHost);
            // 设置用户名、密码
            CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
            credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(userName, password));
            // 连接延时配置
            builder.setRequestConfigCallback(requestConfigBuilder -> {
                requestConfigBuilder.setConnectTimeout(connectTimeOut);
                requestConfigBuilder.setSocketTimeout(socketTimeOut);
                requestConfigBuilder.setConnectionRequestTimeout(connectionRequestTimeOut);
                return requestConfigBuilder;
            });
            // 连接数配置
            builder.setHttpClientConfigCallback(httpClientBuilder -> {
                httpClientBuilder.setMaxConnTotal(maxConnectNum);
                httpClientBuilder.setMaxConnPerRoute(maxConnectNumPerRoute);
                httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider);
                return httpClientBuilder;
            });
            restHighLevelClient = new RestHighLevelClient(builder);
        } catch (NumberFormatException e) {
            log.error("ES 连接池初始化异常");
        }
        return restHighLevelClient;
    }
}

EsUtil 工具类

工具类中,讲到的 index 其实就是 表名称

package com.example.springbootfull.elasticsearchclient.util;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.support.master.AcknowledgedResponse;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.CreateIndexRequest;
import org.elasticsearch.client.indices.CreateIndexResponse;
import org.elasticsearch.client.indices.GetIndexRequest;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.core.TimeValue;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.FetchSourceContext;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.UUID;

/**
 * es 的工具类
 *
 * @author
 */
@Slf4j
@Component
public class EsUtil {

    @Autowired
    private RestHighLevelClient restHighLevelClient;


    /**
     * 关键字
     */
    public static final String KEYWORD = ".keyword";

    /**
     * 创建索引
     *
     * @param index 索引
     * @return
     */
    public boolean createIndex(String index) throws IOException {
        if (isIndexExist(index)) {
            log.error("Index is exits!");
            return false;
        }
        //1.创建索引请求
        CreateIndexRequest request = new CreateIndexRequest(index);
        //2.执行客户端请求
        CreateIndexResponse response = restHighLevelClient.indices().create(request, RequestOptions.DEFAULT);

        log.info("创建索引{}成功", index);

        return response.isAcknowledged();
    }

    /**
     * 删除索引
     *
     * @param index
     * @return
     */
    public boolean deleteIndex(String index) throws IOException {
        if (!isIndexExist(index)) {
            log.error("Index is not exits!");
            return false;
        }
        //删除索引请求
        DeleteIndexRequest request = new DeleteIndexRequest(index);
        //执行客户端请求
        AcknowledgedResponse delete = restHighLevelClient.indices().delete(request, RequestOptions.DEFAULT);

        log.info("删除索引{}成功", index);

        return delete.isAcknowledged();
    }


    /**
     * 判断索引是否存在
     *
     * @param index
     * @return
     */
    public boolean isIndexExist(String index) throws IOException {

        GetIndexRequest request = new GetIndexRequest(index);

        boolean exists = restHighLevelClient.indices().exists(request, RequestOptions.DEFAULT);

        return exists;
    }


    /**
     * 数据添加,正定ID
     *
     * @param jsonObject 要增加的数据
     * @param index      索引,类似数据库
     * @param id         数据ID, 为null时es随机生成
     * @return
     */
    public String addData(JSONObject jsonObject, String index, String id) throws IOException {

        //创建请求
        IndexRequest request = new IndexRequest(index);
        //规则 put /test_index/_doc/1
        request.id(id);
        request.timeout(TimeValue.timeValueSeconds(1));
        //将数据放入请求 json
        IndexRequest source = request.source(jsonObject, XContentType.JSON);
        //客户端发送请求
        IndexResponse response = restHighLevelClient.index(request, RequestOptions.DEFAULT);
        log.info("添加数据成功 索引为: {}, response 状态: {}, id为: {}", index, response.status().getStatus(), response.getId());
        return response.getId();
    }


    /**
     * 数据添加 随机id
     *
     * @param jsonObject 要增加的数据
     * @param index      索引,类似数据库
     * @return
     */
    public String addData(JSONObject jsonObject, String index) throws IOException {
        return addData(jsonObject, index, UUID.randomUUID().toString().replaceAll("-", "").toUpperCase());
    }

    /**
     * 通过ID删除数据
     *
     * @param index 索引,类似数据库
     * @param id    数据ID
     */
    public void deleteDataById(String index, String id) throws IOException {
        //删除请求
        DeleteRequest request = new DeleteRequest(index, id);
        //执行客户端请求
        DeleteResponse delete = restHighLevelClient.delete(request, RequestOptions.DEFAULT);
        log.info("索引为: {}, id为: {}删除数据成功", index, id);
    }


    /**
     * 通过ID 更新数据
     *
     * @param object 要增加的数据
     * @param index  索引,类似数据库
     * @param id     数据ID
     * @return
     */
    public void updateDataById(Object object, String index, String id) throws IOException {
        //更新请求
        UpdateRequest update = new UpdateRequest(index, id);

        //保证数据实时更新
        //update.setRefreshPolicy("wait_for");

        update.timeout("1s");
        update.doc(JSON.toJSONString(object), XContentType.JSON);
        //执行更新请求
        UpdateResponse update1 = restHighLevelClient.update(update, RequestOptions.DEFAULT);
        log.info("索引为: {}, id为: {}, 更新数据成功", index, id);
    }


    /**
     * 通过ID 更新数据,保证实时性
     *
     * @param object 要增加的数据
     * @param index  索引,类似数据库
     * @param id     数据ID
     * @return
     */
    public void updateDataByIdNoRealTime(Object object, String index, String id) throws IOException {
        //更新请求
        UpdateRequest update = new UpdateRequest(index, id);

        //保证数据实时更新
        update.setRefreshPolicy("wait_for");

        update.timeout("1s");
        update.doc(JSON.toJSONString(object), XContentType.JSON);
        //执行更新请求
        UpdateResponse update1 = restHighLevelClient.update(update, RequestOptions.DEFAULT);
        log.info("索引为: {}, id为: {}, 更新数据成功", index, id);
    }


    /**
     * 通过ID获取数据
     *
     * @param index  索引,类似数据库
     * @param id     数据ID
     * @param fields 需要显示的字段,逗号分隔(缺省为全部字段)
     * @return
     */
    public Map<String, Object> searchDataById(String index, String id, String fields) throws IOException {
        GetRequest request = new GetRequest(index, id);
        if (StringUtils.isNotEmpty(fields)) {
            //只查询特定字段。如果需要查询所有字段则不设置该项。
            request.fetchSourceContext(new FetchSourceContext(true, fields.split(","), Strings.EMPTY_ARRAY));
        }
        GetResponse response = restHighLevelClient.get(request, RequestOptions.DEFAULT);
        Map<String, Object> map = response.getSource();
        //为返回的数据添加id
        map.put("id", response.getId());
        return map;
    }

    /**
     * 通过ID判断文档是否存在
     *
     * @param index 索引,类似数据库
     * @param id    数据ID
     * @return
     */
    public boolean existsById(String index, String id) throws IOException {
        GetRequest request = new GetRequest(index, id);
        //不获取返回的_source的上下文
        request.fetchSourceContext(new FetchSourceContext(false));
        request.storedFields("_none_");
        return restHighLevelClient.exists(request, RequestOptions.DEFAULT);
    }

    /**
     * 获取低水平客户端
     *
     * @return
     */
    public RestClient getLowLevelClient() {
        return restHighLevelClient.getLowLevelClient();
    }


    /**
     * 高亮结果集 特殊处理
     * map转对象 JSONObject.parseObject(JSONObject.toJSONString(map), Content.class)
     *
     * @param searchResponse
     * @param highlightField
     */
    public List<Map<String, Object>> setSearchResponse(SearchResponse searchResponse, String highlightField) {
        //解析结果
        ArrayList<Map<String, Object>> list = new ArrayList<>();
        for (SearchHit hit : searchResponse.getHits().getHits()) {
            Map<String, HighlightField> high = hit.getHighlightFields();
            HighlightField title = high.get(highlightField);

            hit.getSourceAsMap().put("id", hit.getId());

            Map<String, Object> sourceAsMap = hit.getSourceAsMap();//原来的结果
            //解析高亮字段,将原来的字段换为高亮字段
            if (title != null) {
                Text[] texts = title.fragments();
                String nTitle = "";
                for (Text text : texts) {
                    nTitle += text;
                }
                //替换
                sourceAsMap.put(highlightField, nTitle);
            }
            list.add(sourceAsMap);
        }
        return list;
    }


    /**
     * 查询并分页
     *
     * @param index          索引名称
     * @param query          查询条件
     * @param size           文档大小限制
     * @param from           从第几页开始
     * @param fields         需要显示的字段,逗号分隔(缺省为全部字段)
     * @param sortField      排序字段
     * @param highlightField 高亮字段
     * @return
     */
    public List<Map<String, Object>> searchListData(String index,
                                                    SearchSourceBuilder query,
                                                    Integer size,
                                                    Integer from,
                                                    String fields,
                                                    String sortField,
                                                    String highlightField) throws IOException {
        SearchRequest request = new SearchRequest(index);
        SearchSourceBuilder builder = query;
        if (StringUtils.isNotEmpty(fields)) {
            //只查询特定字段。如果需要查询所有字段则不设置该项。
            builder.fetchSource(new FetchSourceContext(true, fields.split(","), Strings.EMPTY_ARRAY));
        }
        from = from <= 0 ? 0 : from * size;
        //设置确定结果要从哪个索引开始搜索的from选项,默认为0
        builder.from(from);
        builder.size(size);
        if (StringUtils.isNotEmpty(sortField)) {
            //排序字段,注意如果proposal_no是text类型会默认带有keyword性质,需要拼接.keyword
            builder.sort(sortField + ".keyword", SortOrder.ASC);
        }
        //高亮
        HighlightBuilder highlight = new HighlightBuilder();
        highlight.field(highlightField);
        //关闭多个高亮
        highlight.requireFieldMatch(false);
        highlight.preTags("<span style='color:red'>");
        highlight.postTags("</span>");
        builder.highlighter(highlight);
        //不返回源数据。只有条数之类的数据。
        //builder.fetchSource(false);
        request.source(builder);
        SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);
        log.error("==" + response.getHits().getTotalHits());
        if (response.status().getStatus() == 200) {
            // 解析对象
            return setSearchResponse(response, highlightField);
        }
        return null;
    }
}

开始测试

实体类

package com.example.springbootfull.elasticsearchclient.bean;

import java.math.BigDecimal;
import java.util.Date;


public class EmployeeInfo2 {


    private Long id;

    /**
     * 工号
     */
    private String jobNo;

    /**
     * 姓名
     */
    private String name;

    /**
     * 英文名
     */
    private String englishName;

    /**
     * 工作岗位
     */
    private String job;

    /**
     * 性别
     */
    private Integer sex;

    /**
     * 年龄
     */
    private Integer age;

    /**
     * 薪资
     */
    private BigDecimal salary;

    /**
     * 入职时间
     */
    private Date jobDay;

    /**
     * 备注
     */
    private String remark;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getJobNo() {
        return jobNo;
    }

    public void setJobNo(String jobNo) {
        this.jobNo = jobNo;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getEnglishName() {
        return englishName;
    }

    public void setEnglishName(String englishName) {
        this.englishName = englishName;
    }

    public String getJob() {
        return job;
    }

    public void setJob(String job) {
        this.job = job;
    }

    public Integer getSex() {
        return sex;
    }

    public void setSex(Integer sex) {
        this.sex = sex;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public BigDecimal getSalary() {
        return salary;
    }

    public void setSalary(BigDecimal salary) {
        this.salary = salary;
    }

    public Date getJobDay() {
        return jobDay;
    }

    public void setJobDay(Date jobDay) {
        this.jobDay = jobDay;
    }

    public String getRemark() {
        return remark;
    }

    public void setRemark(String remark) {
        this.remark = remark;
    }

    public EmployeeInfo2() {
    }

    public EmployeeInfo2(Long id, String jobNo, String name, String englishName, String job, Integer sex, Integer age, BigDecimal salary, Date jobDay, String remark) {
        this.id = id;
        this.jobNo = jobNo;
        this.name = name;
        this.englishName = englishName;
        this.job = job;
        this.sex = sex;
        this.age = age;
        this.salary = salary;
        this.jobDay = jobDay;
        this.remark = remark;
    }

    @Override
    public String toString() {
        return "EmployeeInfo{" +
                "id=" + id +
                ", jobNo='" + jobNo + '\'' +
                ", name='" + name + '\'' +
                ", englishName='" + englishName + '\'' +
                ", job='" + job + '\'' +
                ", sex=" + sex +
                ", age=" + age +
                ", salary=" + salary +
                ", jobDay=" + jobDay +
                ", remark='" + remark + '\'' +
                '}';
    }
}

Controller类

package com.example.springbootfull.elasticsearchclient.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.PropertyNamingStrategy;
import com.alibaba.fastjson.serializer.SerializeConfig;
import com.example.springbootfull.elasticsearchclient.bean.EmployeeInfo2;
import com.example.springbootfull.elasticsearchclient.util.EsUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;

@RestController
@RequestMapping("/employeeInfo")
public class EmployeeElasticController {

    @Autowired
    private EsUtil esUtil;

    //==========esUtil================

    @RequestMapping("/createIndex")
    public String createIndex() throws Exception {
        esUtil.createIndex("employee_info_2");
        return "success";
    }

    @RequestMapping("/deleteIndex")
    public String deleteIndex() throws Exception {
        esUtil.deleteIndex("employee_info_2");
        return "success";
    }

    @RequestMapping("/save")
    public String save() throws Exception {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        EmployeeInfo2 employeeInfo = new EmployeeInfo2(6001L, "2001", "我去", "zhangsan", "Java", 1, 19, new BigDecimal("12500.01"), simpleDateFormat.parse("2019-09-10"), "备注");
        //可以帮我把驼峰命名的属性转成下划线格式的(如果你需要的话)
        SerializeConfig config = new SerializeConfig();
        config.propertyNamingStrategy = PropertyNamingStrategy.SnakeCase;
        String json1 = JSON.toJSONString(employeeInfo, config);
        esUtil.addData(JSONObject.parseObject(json1), "employee_info_2", null);
        //不然直接
        //esUtil.addData((JSONObject) JSONObject.toJSON(employeeInfo), "employee_info_2", null);
        return "success";
    }

}

执行save 方法后,可以看到 es 可视化页面上面 出现了 一条数据
(其中的id,由于我给了null,es就随机帮我生成了)
在这里插入图片描述
参考文章:
【1】SpringBoot整合ElasticSearch的两种方式
【2】elasticsearch7.9 java工具类restHighLevelClient精华整理JavaRESTClient
【3】三种方式实现Java对象转json下划线格式

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2120842.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

UEFI——获取UEFI MemoryMap

一、MemoryMap简介 首先讲一下什么是MemoryMap&#xff1f; 内存映射&#xff08;Memory Mapping&#xff09;是一种将文件内容映射到进程的虚拟地址空间的技术。在这种机制下&#xff0c;文件可以视为内存的一部分&#xff0c;从而允许程序直接对这部分内存进行读写操作&…

电动车乱停放识别摄像头

电动车乱停放是城市交通管理中常见的问题&#xff0c;给道路通行和停车场管理带来了诸多困扰。为了有效解决这一问题&#xff0c;人们研发了电动车乱停放识别摄像头&#xff0c;这种设备结合了人工智能技术和监控摄像技术&#xff0c;能够实时监测并识别电动车乱停放情况&#…

python日常刷题(二)

前言&#xff1a;本文记录2024年4月9日至2024年4月13日做题时遇到的几个问题&#xff08;错题本&#xff09;&#xff1a; &#x1f3ac;个人简介&#xff1a;努力学习ing &#x1f4cb;本专栏&#xff1a;python日常刷题 &#x1f380;CSDN主页&#xff1a;愚润求学 文章目录 …

uniapp苹果端与安卓端兼容性问题的处理

目录 第一个问题&#xff0c;苹果端页面有下拉回弹的效果&#xff0c;安卓端没有。解决苹果端的问题&#xff0c;在pages.json中对需要的页面&#xff0c; 第二个问题&#xff0c;安卓端页面滚动到底部触发onReachBottom页面生命周期函数&#xff0c;而苹果端无法触发&#xf…

2024年PDF转换器大集合:哪4款是互联网人的首选?

嘿&#xff0c;朋友们&#xff0c;你们知道吗&#xff1f;那些在办公室里看起来特别能干的大佬们&#xff0c;他们好像总能很快地把各种文件变来变去&#xff0c;好像有什么特异功能似的。告诉你们吧&#xff0c;他们其实就是用了几款特别牛的PDF转换工具&#xff01;今天&…

前端打包装包——设置镜像

1、打包失败&#xff0c;因为没装包&#xff0c;装包失败&#xff0c;因为装包的源错误 npm config get registry npm config set registry https://registry.npmmirror.com/npm install npm run build还是失败&#xff0c;因为缺少了包&#xff0c;在package.json文件中没有包…

Centos7.9 安装Elasticsearch 8.15.1(图文教程)

本章教程,主要记录在Centos7.9 安装Elasticsearch 8.15.1的整个安装过程。 一、下载安装包 下载地址: https://www.elastic.co/cn/downloads/past-releases/elasticsearch-8-15-1 你可以通过手动下载然后上传到服务器,也可以直接使用在线下载的方式。 wget https://artifacts…

Docker 部署 Seata (图文并茂超详细)

部署 Seata ( Docker ) [Step 1] : 创建对应的**seata**数据库, 也就是下面的的**seata.sql**文件 seata.sql [Step 2] : 拉取 Seata 镜像 docker pull seataio/seata-server:1.5.2[Step 3] : 创建目录 ➡️ 创建容器 ➡️ 拷贝文件 ➡️ 授权文件 ➡️ 删除容器 # 创建…

热点文章轻松生成?一篇测评告诉你ChatGPT的神奇能力

个人名片 &#x1f393;作者简介&#xff1a;java领域优质创作者 &#x1f310;个人主页&#xff1a;码农阿豪 &#x1f4de;工作室&#xff1a;新空间代码工作室&#xff08;提供各种软件服务&#xff09; &#x1f48c;个人邮箱&#xff1a;[2435024119qq.com] &#x1f4f1…

【视频教程】遥感云大数据在灾害、水体与湿地领域典型案例实践及GPT模型应用

前期我们分别以Javascript和Python为编程语言&#xff0c;成功举办了数期关于GEE遥感大数据分析处理的基础培训课程&#xff0c;得到了来多个行业的学员的广泛参与和支持。应广大科研工作者的要求&#xff0c;本次课程将聚焦目前遥感应用最热门领域之一的灾害、水体及湿地领域&…

多线程篇(阻塞队列- LinkedTransferQueue)(持续更新迭代)

目录 一、简介 二、基本原理 三、jdk8 内部属性 4个常量值 transfer tryAppend take() awaitMatch boolean remove(Object o) 四、jdk17 主要参数 put/offer take() remove() 五、与synchronousqueue 区别 六、知识小结 一、简介 LinkedTransferQueue是一个由…

手撕Python之文件操作

1.编码 编码---encode() 解码---decode() #编码(encode):将我们能够识别的文字&#xff0c;转换为计算机能够识别的内容 print(你好.encode())#默认utf-8 #b\xe4\xbd\xa0\xe5\xa5\xbd #将你好翻成进制数#解码&#xff08;decode&#xff09;:将计算机能识别的内容&#xff0c…

兼顾身份保护和文本对齐!中山大学等提出CoRe:任意提示的文本到图像个性化生成!

文章链接&#xff1a;https://arxiv.org/pdf/2408.15914 亮点直击 CoRe只用于输出embedding和注意力图&#xff0c;不需要生成图像&#xff0c;可以用于任意提示。 在身份保护和文本对齐方面表现出优越的性能&#xff0c;特别是对于需要高度视觉可变性的提示。 除了个性化一般…

2. Python之注释及缩进以及print和input函数使用

一. Python代码中的注释及缩进 Python中注释有单行注释&#xff0c;多行注释&#xff0c;声明注释 单行注释使用符号#&#xff0c;从#开始&#xff0c;后面到本行末尾都是注释内容。多行注释可以使用’‘’ ‘’三个引号&#xff0c;三个引号内的内容都是注释声明注释&#x…

密钥加密机的定义与分类

密钥加密机&#xff0c;也称为加密机或硬件加密模块(HSM, Hardware Security Module)&#xff0c;是信息安全领域中的核心设备。它通过密码学原理和密钥管理技术&#xff0c;对敏感数据进行加密保护&#xff0c;确保数据在传输和存储过程中的安全性。以下是对密钥加密机的详细解…

开始一个WPF项目时的记忆重载入

目前在工业软件的UI开发方案选择中&#xff0c;WPF仍然是一个重要的选项。 但是其固有的复杂性&#xff0c;对于像我这样&#xff0c;并不是一直在从事界面开发的人来说&#xff0c;每次重启&#xff0c;都需要一两天的适应的时间。所以这里稍微写一个笔记。 还是老办法&…

分享一款520表白节JS代码

源码介绍 今天给大家分享一款JS表白源码 js会随 随机颜色心形跟随鼠标互动520表白节女神表白利器&#xff01; 修改的话就搜索&#xff1a;LOVEh 就能找到这个英文了。 效果预览 源码获取 分享一款520表白节JS代码 百度网盘提取码&#xff1a;2yar&#xff1a;https://pan.…

JavaScript高级——回调函数

1、回调函数的含义 ① 你定义的 ② 你没有调 ③ 但最终他执行了&#xff08;某个时刻或者某个条件下&#xff09; 2、常见的回调函数 ① dom事件回调函数 —— 发生事件的dom元素 ② 定时器回调函数 —— window ③ ajax请求回调函数 ④ 生命周期回调函数 本文分享…

【Adaptive AutoSAR 源码解析01】通信中间件技术总览

https://www.autosar.org/fileadmin/standards/R21-11/AP/AUTOSAR_EXP_ARAComAPI.pdf#page=8&zoom=100,94,473

pip install “git+https://xxx“报错error: subprocess-exited-with-error

有时候即使使用科学上网&#xff0c;可以正常访问github也会发生pip install “githttps://xxx“报错 如 解决方法&#xff1a; 我们可以将pip install “githttps://xxx“分为两步&#xff1a; 第一步&#xff1a; pip install "githttps://xxx" 第二步&#…