Spring 整合 Elasticsearch

SpringBoot集成Elasticsearch教程 本文以ElasticSearch7.12.1为例,ElasticSearch 是一个分布式、可扩展、高性能的检索与数据分析引擎。ElasticSearch 基于 Java 编写,通过对Lucene进一步封装 ,将搜索的复杂性屏蔽起来,开发者只需要一套简单的 RESTful API 就可以操作全文检索。 阅读详情

确定引入版本

Spring 项目中专门有链接ES的组件 ,可以方便快速的链接ES。官方文档一般都会有版本对照的说明 版本对照
在这里插入图片描述
同时也提供了更为方便的“Spring Boot Starter Data Elasticsearch” 。
在这里我们使用的是“Spring Boot Starter Data Elasticsearch » 2.6.15” 这里要注意结合自己项目版本选择正确的“Spring Boot Starter Data Elasticsearch“版本
在这里插入图片描述
引入到项目即可

			<dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
                <version>2.6.15</version>
            </dependency>

编写启动类

import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.elasticsearch.client.ClientConfiguration;
import org.springframework.data.elasticsearch.client.RestClients;
import org.springframework.data.elasticsearch.config.AbstractElasticsearchConfiguration;

@Configuration
public class ElasticsearchConfig extends AbstractElasticsearchConfiguration {

    @Value("${elasticsearch-config.connected}")
    private String connected;

    @Value("${elasticsearch-config.userName}")
    private String userName;

    @Value("${elasticsearch-config.password}")
    private String password;

    @Override
    public RestHighLevelClient elasticsearchClient() {
        final ClientConfiguration clientConfiguration = ClientConfiguration.builder()
                // ES ip:端口
                .connectedTo(connected)
                // ES 账号密码
                .withBasicAuth(userName, password)
                .withConnectTimeout(15000L)
                .withSocketTimeout(3000L)
                .build();
        return RestClients.create(clientConfiguration).rest();
    }
}

编写映射

我们仅需简单的注解配置即可完成java 实体和 ES文档的映射
这里推荐一个 大佬的博文

import lombok.*;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.annotations.FieldType;

@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = true)
@Data
@NoArgsConstructor
@AllArgsConstructor
// 这里indexName 要与 ES索引名对应,别名也行。
@Document(indexName = "product_spu", createIndex = false)
public class ProductSpuEntity extends BaseEntity {

    @Field(type = FieldType.Text)
    private String name;

    @Field(type = FieldType.Text, name = "name_pinyin")
    private String namePinyin;

    @Field(type = FieldType.Text, name = "product_code")
    private String productCode;

    @Field(type = FieldType.Text, name = "spec_code")
    private String specCode;

    @Field(type = FieldType.Text, name = "product_spec")
    private String productSpec;

    @Field(type = FieldType.Text, name = "sku_number")
    private String skuNumber;

    @Field(type = FieldType.Integer, name = "product_type")
    private Integer productType;

    @Field(type = FieldType.Integer)
    private Integer status;

    @Field(type = FieldType.Text)
    private String remark;

}

编写请求示例

import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.xxxx.component.base.config.ElasticsearchBaseConfig;
import com.xxxx.domain.dto.foundation.pagehelp.entity.PageBO;
import com.xxxx.domain.dto.foundation.pagehelp.util.PageUtil;
import com.xxxx.foundation.base.ElasticsearchHighlightContext;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.MultiMatchQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.ElasticsearchOperations;
import org.springframework.data.elasticsearch.core.SearchHit;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.stereotype.Component;

import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

@Component
public class ProductQueryManager {

    @Autowired
    private ElasticsearchOperations elasticsearchOperations;

    @Autowired
    private ElasticsearchHighlightContext elasticsearchHighlightContext;

    @Autowired
    private ElasticsearchBaseConfig elasticsearchBaseConfig;

    public <T> List<T> spuQuery(Long corpId, String keyWord, Integer pageNum, Integer pageSize,
                                Boolean hideStop, Boolean needProductBundle,
                                Class<T> clazz) {
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery().must(QueryBuilders.matchQuery("corp_id", corpId.toString()));
        if (BooleanUtils.isTrue(hideStop)) {
            boolQueryBuilder.must(QueryBuilders.termQuery("status", 1));
        }
        if (BooleanUtils.isFalse(needProductBundle)) {
            boolQueryBuilder.must(QueryBuilders.termQuery("product_type", 1));
        }
        // boost 设置权重  caseInsensitive 忽略大小写
        boolQueryBuilder.should(QueryBuilders.termQuery("name", keyWord).boost(elasticsearchBaseConfig.getProductNameTermBoost()).caseInsensitive(true));
        boolQueryBuilder.should(QueryBuilders.termQuery("sku_number", keyWord).boost(elasticsearchBaseConfig.getSkuNumberTermBoost()).caseInsensitive(true));
        if (isPureLetters(keyWord)) {
            // 若是纯英文字符则查询拼音
            boolQueryBuilder.should(QueryBuilders.termQuery("name.pinyin", keyWord).boost(elasticsearchBaseConfig.getProductNameTermBoost()));
        }
        boolQueryBuilder.should(QueryBuilders.termQuery("product_code", keyWord).boost(elasticsearchBaseConfig.getProductCodeTermBoost()).caseInsensitive(true));
        MultiMatchQueryBuilder multiMatchQueryBuilder = QueryBuilders.multiMatchQuery(keyWord)
                .field("name", elasticsearchBaseConfig.getProductNameFuzzyBoost())
                .field("name.ngram", elasticsearchBaseConfig.getProductNameFuzzyBoost())
                .field("product_code")
                .field("product_code.ngram")
                .field("sku_number", elasticsearchBaseConfig.getProductSkuNumberFuzzyBoost())
                .field("sku_number.ngram", elasticsearchBaseConfig.getProductSkuNumberFuzzyBoost())
                .field("product_spec", elasticsearchBaseConfig.getProductSpecFuzzyBoost())
                .field("product_spec.ngram", elasticsearchBaseConfig.getProductSpecFuzzyBoost())
                .field("spec_code", elasticsearchBaseConfig.getSpecCodeFuzzyBoost())
                .field("spec_sku_number", elasticsearchBaseConfig.getProductSkuNumberFuzzyBoost())
                .field("spec_sku_number.ngram", elasticsearchBaseConfig.getProductSkuNumberFuzzyBoost())
                .field("spec_code.ngram");
        if (isPureLetters(keyWord)) {
            multiMatchQueryBuilder.field("name.pinyin", elasticsearchBaseConfig.getProductNameFuzzyBoost())
                    .field("name_pinyin", elasticsearchBaseConfig.getProductNameFuzzyBoost())
                    .field("sku_number.pinyin", elasticsearchBaseConfig.getProductSkuNumberFuzzyBoost())
                    .field("spec_sku_number.pinyin", elasticsearchBaseConfig.getProductSkuNumberFuzzyBoost())
                    .field("product_spec.pinyin", elasticsearchBaseConfig.getProductSpecFuzzyBoost());
        }
        boolQueryBuilder.should(multiMatchQueryBuilder);
        HighlightBuilder highlightBuilder = new HighlightBuilder()
                .field("name")
                .field("name.ngram")
                .field("product_code")
                .field("product_code.ngram")
                .field("sku_number")
                .field("sku_number.ngram")
                .field("product_spec")
                .field("product_spec.ngram")
                .field("spec_code")
                .field("spec_code.ngram");
        if (isPureLetters(keyWord)) {
            highlightBuilder.field("name.pinyin")
                    .field("sku_number.pinyin")
                    .field("product_spec.pinyin");
        }
        // 至少需要满足一个should条件
        boolQueryBuilder.minimumShouldMatch(1);
        return nativeSearchQuery(boolQueryBuilder, highlightBuilder, pageNum, pageSize, clazz);
    }


    public <T> List<T> nativeSearchQuery(QueryBuilder queryBuilder, HighlightBuilder highlightBuilder, Integer pageNum, Integer pageSize, Class<T> clazz) {
        PageBO page = new PageBO();
        page.setPageNum(pageNum);
        page.setPageSize(pageSize);
        // es分页从0开始的
        pageNum = pageNum - 1;
        if (pageNum < 0) {
            pageNum = 0;
        }
        NativeSearchQuery nativeSearchQuery = new NativeSearchQueryBuilder()
                // 查询设置
                .withQuery(queryBuilder)
                // 高亮设置
                .withHighlightBuilder(highlightBuilder)
                // 分页设置
                .withPageable(PageRequest.of(pageNum, pageSize))
                .build();
        Set<String> highlightSet = Sets.newHashSet();
        SearchHits<T> searchHits = elasticsearchOperations.search(nativeSearchQuery, clazz);
        // 处理高亮数据
        List<SearchHit<T>> searchHitList = searchHits.stream().collect(Collectors.toList());
        for (SearchHit<T> searchHit : searchHitList) {
            Map<String, List<String>> highlightFields = searchHit.getHighlightFields();
            if (MapUtils.isNotEmpty(highlightFields)) {
                highlightFields.values().forEach(data -> {
                    data.forEach(highlightValues -> {
                        highlightSet.addAll(extractHighlightValue(highlightValues));
                    });
                });
            }
        }
        page.setTotal(searchHits.getTotalHits());
        PageUtil.setPage(page);
        // 将高亮数据放入本地线程变量,elasticsearchHighlightContext 是一个 TransmittableThreadLocal,自己建的
        elasticsearchHighlightContext.setContext(Lists.newArrayList(highlightSet));
        return searchHits.stream().map(SearchHit::getContent).collect(Collectors.toList());
    }

    public Set<String> extractHighlightValue(String str) {
        String regex = "<em>(.*?)</em>";
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(str);
        Set<String> extractedChars = new HashSet<>();
        while (matcher.find()) {
            String extractedChar = matcher.group(1);
            if (StringUtils.isBlank(extractedChar)) {
                continue;
            }
            extractedChars.add(extractedChar);
        }
        return extractedChars;
    }

    public boolean isPureLetters(String str) {
        return str.matches("[a-zA-Z]+");
    }
}
spring中使用Elasticsearch的代码实现 在使用Elasticsearch之前,先给大家聊一点干货。 1.      ES和solr都是作为全文搜索引擎出现的。都是基于Lucene的搜索服务器。 2.   ES不是可靠的存储系统,不是数据库,它有丢数据的风险。 3.   ES不是实时系统,数据写入成功只是trans log成功(类似于mysql的bin log),写入成功后立刻查询查不到是正常的。因为数据此刻可能还在内存里而不是进 阅读详情

相关推荐

Spring Boot整合Elasticsearch,最新最全教程

要想快速入门新技术,英文文档的阅读能力必不可少。本篇文章主要参考《Spring Data Elasticsearch》Spring Boot整合Elasticsearch的官方文档。 Elasticsearch官网参考文档:https://www.elastic.co/guide/index.html Elasticsearch官方下载地址:https://www.elastic.co/cn/downloads/elasticsearch Elasticsearch目前最近版本为:7.10.1 最近系统.

Cloud-Future的博客 10万+

SpringBoot-starter-data整合Elasticsearch

1.前言 本文主要讲解,springBoot 使用spring-boot-starter-data-elasticsearch方式整合Elasticsearch 文末附源码 什么是Spring Data ElasticSearch   Spring Data ElasticSearch 基于 spring data API 简化 elasticSearch操作,将原始操作elasticSearch的客户端API进行封装 。Spring Data为Elasticsearch项目提供集成搜索引擎。Spring

程序员小强的博客 3万+

【牛客网论坛】第6章:Elasticsearch,分布式搜索引擎(Spring整合Elasticsearch)

Elasticsearch2 Spring整合Elasticsearch2.1 引入依赖(spring-boot-starter-data-elasticsearch)2.2 配置Elasticsearch(配置cluster-name、cluster-nodes)2.2.1 application.properties2.2.2 解决Netty冲突问题2.3 Spring Data Elasticsearch(调用spring提供的关于es的API访问es服务器,将数据库里的帖子存到es服务器里,然后从e

qq_60225495的博客 1144

Elasticsearch7.x——spring-boot-starter-data-elasticsearch详解

Spring Data Elasticsearch是Spring Data项目下的一个子模块。查看 Spring Data的官网:http://projects.spring.io/spring-data/Spring Data 的使命是给各种数据访问提供统一的编程接口,不管是关系型数据库(如MySQL),还是非关系数据库(如Redis),或者类似Elasticsearch这样的索引数据库。从而简化开发人员的代码,提高开发效率。Spring Boot与Elasticsearch的对应版本:</

吴声子夜歌的博客 5985

springboot整合全文搜索引擎Elasticsearch | Spring Boot 28

???? Java学习路线配套文章:Java学习路线总结,搬砖工逆袭Java架构师(全网最强) ???? 基础推荐:Java基础教程系列 ???? 实战推荐:Spring Boot基础教程 ???? 简介:Java领域优质创作者????、优快云哪吒公众号作者✌ 、Java架构师奋斗者???? ???? 扫描主页左侧二维码,加入群聊,一起学习、一起进步 ???? 欢迎点赞 ???? 收藏 ⭐留言 ???? 目录一、Elasticsearch简介二、下载与安装1、Elasticsearch官网下载地址2、下

学Java,找哪吒 1万+

Spring Boot 与 Elasticsearch 搜索引擎整合

数据同步:如何将关系型数据库(如MySQL)中的数据实时同步到ES?查询性能:如何优化复杂查询(如多条件过滤、聚合)的响应时间?分布式一致性:ES集群分片/副本机制下,如何保证数据的可靠性?开发效率:如何避免重复编写ES客户端代码,实现"面向对象"的搜索开发?使用@Document和@Field@Data@Document(indexName = "product", shards = 3, replicas = 2) // 3分片,2副本@Id // 对应ES文档的_id字段。

AI架构全栈开发实战笔记 503

Spring整合Easy-ES

详细步骤及讲解Spring中如何使用Easy-ES实现各种功能

LoveTalk的博客 2125

Spring Boot整合Elasticsearch搜索引擎实战项目

简介:Spring Boot与Elasticsearch是现代IT开发中的核心技术组合,前者简化Java应用开发,后者提供高性能分布式全文搜索能力。本项目“springboot-elasticSearch”为一个开箱即用的集成模板,涵盖Spring Boot自动配置与Elasticsearch高效检索的完整实现,支持索引管理、数据增删改查、复杂查询及性能优化。

weixin_42466723的博客 1201

知识点13--spring boot整合elasticsearch以及ES高亮

本章知识点沿用知识点11的项目,介绍如何使用spring boot整合ES,没有ES的去我主页中可以看到ES如何搭建不管你有没有ES,最好是没有,因为一定要知道一点,一定要去官网查一下你当前用的spring boot data es的版本是不是和你自己ES服务器所匹配的,这一点简直是天坑,spring boot提供的es封装API对es的版本要求相当苛刻,对不上就用不了,很多人折在版本问题,奉劝大家一句,除非正式的项目开发上,团队会给你提供需要版本的jar,正式开发本身版本都是经过架构师仔细考虑并且版本方面

别人笑我太疯癫,我笑他人看不穿。 3222

VsCode+JLink+GCC替代Keil开发GD32程序-个人总结

对个人使用vscode+Jlink开发GD32程序做了总结,供需要者参考。

MyCollege1999的博客 2763

Ansys口腔正畸有限元分析:从几何处理到接触设定的全流程解析

本文详细解析了Ansys在口腔正畸有限元分析中的全流程应用,从几何处理到接触设定,帮助医生精准预测牙齿移动趋势。通过有限元建模技术,可同时观察牙齿-牙周膜-牙槽骨的力学响应,显著提升矫治效果预测准确率。文章还分享了实用技巧和参数设置建议,适用于正畸医生和工程师。

weixin_30897233的博客 348

Day28:ElasticSearch入门、Spring整合ES、开发社区搜索功能

Elasticsearch简介Elasticsearch术语。

weixin_43303286的博客 2622

速腾RS-LiDAR-16激光雷达ROS配置全攻略:从硬件连接到Rviz点云可视化

本文详细介绍了速腾RS-LiDAR-16激光雷达在ROS环境中的配置与使用全攻略,涵盖硬件连接、网络配置、ROS驱动安装及Rviz点云可视化等关键步骤。通过实战案例和技术解析,帮助开发者快速实现激光雷达数据采集与处理,提升机器人感知系统的部署效率。

ooo22的博客 249

Springboot整合spring-boot-starter-data-elasticsearch

spring-data-elasticsearch的查询,相当于原生的es依赖而言,多了一些注解封装、repository类等,但是对于复杂查询还是没有办法很简便,因此便有了第三方的依赖Easy-es的诞生,类似于Mybatis-plus的方式,对于新手对es的使用比较友好,后面会进行讲解最后:我是Walker,一个热爱分享的程序员,希望我的输出能够帮助到你。

Think_and_work的博客 1908

上下相机对位,上下贴合,上下相机映射对位场景案例

上下相机对位,上下贴合,上下相机映射对位场景案例

视觉人机器视觉的博客 1万+

什么是 SAP PCE?

SAP Private Cloud Edition 是一种基于云计算的部署模式,它结合了公有云的灵活性和私有云的安全性,为企业提供了量身定制的云服务。在 PCE 环境中,SAP 托管和维护客户的应用系统(如 SAP S/4HANA、SAP SuccessFactors 或 SAP BW/4HANA),同时客户拥有更高的定制化权限。专属环境:每个客户在云中拥有独立的资源,这保障了更高的安全性和性能。全面托管:SAP 提供基础架构、系统管理和更新服务,降低了客户的运维成本。灵活扩展。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 2244

Windows安装Elasticsearch及Spring Boot整合ES教程

通过以上步骤,我们实现了在Windows系统上安装Elasticsearch,并在Spring Boot中完成了与Elasticsearch的整合。

qq_56694800的博客 2195

飞牛NAS 0day漏洞导致断网?完整的排查修复方案来了(含一键检测修复工具)

家里网络莫名断网,折腾十来天才发现是NAS被0day漏洞利用了?🔍 本文详细记录了从发现问题到最终解决的全过程,包括如何自查系统是否被入侵、使用检测脚本和专杀脚本进行修复,以及如何通过端口管理、访问控制、监控预警等措施加固系统安全 🔒,帮助遇到同样问题的用户快速排查和解决NAS安全风险 ✅

XiaoqiangClub的博客 5515

Springboot整合ES(2)spring-boot-starter-data-elasticsearch

spring-data-elasticsearch的查询,相当于原生的es依赖而言,多了一些注解封装、repository类等,但是对于复杂查询还是没有办法很简便,因此便有了第三方的依赖Easy-es的诞生,类似于Mybatis-plus的方式,对于新手对es的使用比较友好,后面会进行讲解最后:我是Walker,一个热爱分享的程序员,希望我的输出能够帮助到你。

Think_and_work的博客 2214

uniapp [全端兼容] - 详细实现接入使用海康威视监控云端显示及控制功能,网站集成安装海康监控及实时监控显示、摄像头控制,实时推流、回放、放大缩小画面、视频画面截图、截屏抓拍及播放器解决延迟教程

uniapp,h5移动端网页,微信小程序,支付宝小程序,Android安卓,苹果ios,app,nvue,vue,海康威视,海康监控,摄像头监控,实时监控画面,海康插件,无法连接,报错,uniApp对接海康处理接口认证规则,监控实时预览和回放功能,海康api接口,安全认证,海康开放平台,官方文档,播放海康摄像头的监控视频,海康实时监控播放详细步骤,web,黑屏,视频播放,回放,视频流地址,取流协议,视频sdk播放,hik,rtsp,rtmp,hls,ws,网站,网页,h5页面,后台管理系统,对接海康监控设备

🏆 前端领域优质创作者 1万+

【原创教程】西门子1500与施耐德伺服的通讯以及调试

该函数块主要描述伺服的手动,左边的引脚Forward是指伺服手动正转,Backward是指伺服手动反转,Fast是指手动的某个方向为快速运行,TipPos手册上描述为固定值,WaitTIme是指伺服手动的相应时间,VeloSlow指伺服手动正常慢速运动的速度,VeloFast指伺服手动快速运动的速度,Acceleration是指伺服手动的加速度,Decelertion是指伺服手动的减速度。该函数块用于伺服停止,左边的引脚Execute为伺服停止执行,Deceleration含义为减速,Axis为轴。

Qinmingyue13的博客 1374

Spring整合ElasticSearch

ES集群: ES为Java内置了两套客户端(通过9300端口通信) ps:其他语言使用9200端口与ES通信 集群状态 结构化语句: 项目 结构化查询(Query DSL) 结构化过滤(Filter DSL) 目的 询问每个文档目标字段的值与目标值的匹配程度如何 检查是否包含特定值 适用范围 全文本搜索,相关性评分 剩下的所有 性能 因为需要计算相关性,耗时,且不可缓...

码农的在线笔记 1610

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

Spring和Elasticsearch全文搜索整合详解

Spring和Elasticsearch全文搜索整合详解 一、概述 ElasticSearch是一个基于Lucene的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口。Elasticsearch是用Java开发的,并作为Apache许可条款下的开放源码发布,是当前流行的企业级搜索引擎。 ES是ElasticSearch的缩写; ELK是三个开源软件的缩写,分别...

feiyangtianyao的专栏 3457

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

spring整合es的步骤

spring整合es 1.导入依赖(在cms系统pom文件里导入,容易引起jar包冲突,因此解决方式) 2.编写配置文件(让spring容器来加载这个配置文件) 3.修改ip地址和端口号,es仓库扫描包的位置 4.根据es仓库所在包,创建操作es的仓库接口 5.仓库接口继承ElasticsearchRepository接口,此时我们的仓库接口,就自动具备了CRUD的功能了(泛型里第一个参数:要操作...

weixin_46301294的博客 1531

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

es springboot 不设置id_Spring Boot 整合 elasticsearch

一、简介我们的应用经常需要添加检索功能,开源的 ElasticSearch 是目前全文搜索引擎的 首选。他可以快速的存储、搜索和分析海量数据。Spring Boot通过整合Spring Data ElasticSearch为我们提供了非常便捷的检索功能支持;Elasticsearch是一个分布式搜索服务,提供Restful API,底层基于Lucene,采用 多shard(分片)的方式保证数据安全...

weixin_39622980的博客 207
上一篇: Elasticsearch 排序与评分问题
下一篇: mybatis-dynamic-sql 升级遇到的坑
GrayGo
博客等级 码龄10年 82粉丝 28原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值