【Elasticsearch 中间件】Elasticsearch 客户端使用案例
文章目录
- 一、安装 Elasticsearch
- 1.1 启动 Elasticsearch
- 1.2 启动 Kibana
- 二、客户端代码
- 2.1 导入依赖
- 2.2 配置 application.yaml
- 2.3 定义实体类
- 2.4 连接 Elasticserach
- 2.5 定义 Service 层接口
- 2.6 实现 Service 层功能
- 三、测试项目
- 3.1 添加数据
- 3.2 搜索数据
- 3.3 更新数据
- 3.4 删除数据
- 参考资料
完整案例代码:https://github.com/idealzouhu/java-demos/tree/main/middleware-demos/spring-boot-elasticsearch/elasticsearch-client
一、安装 Elasticsearch
1.1 启动 Elasticsearch
运行以下命令启动 Elasticsearch :
$ docker network create elastic$ docker pull docker.elastic.co/elasticsearch/elasticsearch:7.17.26$ docker run --name es01-test ^--net elastic ^-p 127.0.0.1:9200:9200 ^-p 127.0.0.1:9300:9300 ^-e "discovery.type=single-node" ^-e "xpack.security.enabled=true" ^-e "ELASTIC_PASSWORD=Elastic@123456" ^-e "KIBANA_PASSWORD=Kibana@123456" ^docker.elastic.co/elasticsearch/elasticsearch:7.17.26
其中,具体参数的含义如下:
-e "xpack.security.enabled=true":启用 Elasticsearch 的安全功能。具体细节查看 Set up minimal security for Elasticsearch-e "ELASTIC_PASSWORD=Elastic@123456":为elastic用户设置密码。elastic用户拥有超级权限。-e "KIBANA_PASSWORD=Kibana@123456":为kibana_system用户设置密码。kibana_system用户是一个为 Kibana 服务账户 创建的专用用户。它有足够的权限来与 Elasticsearch 通信,但它并没有elastic用户的超高权限。
1.2 启动 Kibana
Kibana 主要用来可视化和管理Elasticsearch数据。
运行以下命令启动 Kibana:
$ docker pull docker.elastic.co/kibana/kibana:7.17.26$ docker run --name kib01-test ^--net elastic ^-p 127.0.0.1:5601:5601 ^-e "ELASTICSEARCH_HOSTS=http://es01-test:9200" ^-e "ELASTICSEARCH_USERNAME=elastic" ^-e "ELASTICSEARCH_PASSWORD=Elastic@123456" ^docker.elastic.co/kibana/kibana:7.17.26
其中,具体参数的含义如下:
-
ELASTICSEARCH_HOSTS=http://es01-test:9200: 指定了 Kibana 应该连接到哪个 Elasticsearch 节点。 -
ELASTICSEARCH_USERNAME=elastic: 指定 Kibana 使用的用户名是elastic。 -
ELASTICSEARCH_PASSWORD=Elastic@123456:elastic用户的密码。
注意,我们也可以直接在 HTTP 请求里面设置用户名和参数,例如
curl -u elastic:your_elastic_password http://localhost:9200
在启动 Kibana 后,访问 Kibana 可视化界面 http://localhost:5601。
二、客户端代码
2.1 导入依赖
创建 Spring Boot 3.0.6 项目,导入相关依赖:
<dependency><groupId>co.elastic.clients</groupId><artifactId>elasticsearch-java</artifactId><version>7.17.26</version><exclusions><exclusion><groupId>org.elasticsearch.client</groupId><artifactId>elasticsearch-rest-client</artifactId></exclusion></exclusions>
</dependency><dependency><groupId>org.elasticsearch.client</groupId><artifactId>elasticsearch-rest-client</artifactId><version>7.17.26</version>
</dependency><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>2.17.0</version>
</dependency>
如果遇到相关依赖冲突,可以查看 Installation | Elasticsearch Java API Client 7.17
2.2 配置 application.yaml
spring:application:name: elasticsearch-client# 打印 es 的 http 请求,适合在开发调试中使用,正式环境请关闭
logging:level:tracer: TRACE
2.3 定义实体类
@Data
@AllArgsConstructor
@RequiredArgsConstructor
public class Account {// ES中 ducument 的 _idprivate String id;// 解决ES中字段与实体类字段不一致的问题@JsonProperty("account_number")private Long accountNumber;private String address;private Integer age;private Long balance;private String city;private String email;private String employer;private String firstname;private String lastname;private String gender;private String state;
}
2.4 连接 Elasticserach
@Configuration
public class ElasticsearchConfig {/*** 创建并返回一个 Elasticsearch 客户端。** <p>* 使用 RestClientBuilder 构建 RestClient,并使用 BasicCredentialsProvider 设置用户名和密码。* <a href="https://www.elastic.co/guide/en/elasticsearch/client/java-api-client/7.17/connecting.html">官方客户端连接教程</a>* <a href="https://www.elastic.co/guide/en/elasticsearch/client/java-api-client/7.17/_basic_authentication.html">官方基本认证教程</a>* </p>** @return 初始化好的 Elasticsearch 客户端*/@Beanpublic ElasticsearchClient esClient() {// 1. 配置认证String userName = "elastic";String password = "Elastic@123456";final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(userName, password));// 2. 创建 low-level 客户端(使用身份验证)RestClient restClient = RestClient.builder(new HttpHost("localhost", 9200)) // 指定 Elasticsearch 服务器的主机名和端口号.setHttpClientConfigCallback(httpClientBuilder ->httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider)).build();// 3. 创建传输对象,使用 Jackson 映射器将 Java 对象转换为 JSON 格式ElasticsearchTransport transport = new RestClientTransport(restClient, new JacksonJsonpMapper());// 4. 创建 API 客户端return new ElasticsearchClient(transport);}}
2.5 定义 Service 层接口
public interface AccountElasticsearchService {/*** 将 Account 对象索引到 Elasticsearch 中。** @param account 需要索引的账户对象* @throws IOException 当 Elasticsearch 请求失败时抛出*/void indexAccount(Account account) throws IOException;/*** 批量将多个 Account 对象索引到 Elasticsearch 中。** @param accounts 需要索引的账户对象列表* @throws IOException 当 Elasticsearch 请求失败时抛出*/public void indexMultipleAccounts(List<Account> accounts) throws IOException;/*** 根据账户编号搜索账户信息。** @param accountNumber 账户编号* @return 匹配的账户信息,以字符串形式返回* @throws IOException 当 Elasticsearch 请求失败时抛出*/String searchAccountByAccountNumber(Long accountNumber) throws IOException;/*** 根据账户 ID 从 Elasticsearch 获取账户信息。** @param id 账户 ID* @return 对应账户的详细信息* @throws IOException 当 Elasticsearch 请求失败时抛出*/String searchAccountById(String id) throws IOException;/*** 根据 firstname 和 age 查询账户。** @param firstName 姓名* @param age 年龄* @throws IOException 当 Elasticsearch 请求失败时抛出*/public void searchByNameAndAge(String firstName, int age) throws IOException;/*** 更新账户信息。** @param account 修改后的账户对象* @return 返回更新结果信息* @throws IOException 当 Elasticsearch 请求失败时抛出*/String updateAccountById(Account account) throws IOException;/*** 根据账户 ID 从 Elasticsearch 中删除账户信息。** @param accountId 要删除的账户 ID* @return 返回删除结果信息* @throws IOException 当 Elasticsearch 请求失败时抛出*/String deleteAccountById(String accountId) throws IOException;}
2.6 实现 Service 层功能
@Slf4j
@Service
@RequiredArgsConstructor
public class AccountElasticsearchServiceImpl implements AccountElasticsearchService {private final ElasticsearchClient esClient;/*** 将 Account 对象索引到 Elasticsearch 中。** @param account 需要索引的账户对象* @throws IOException 当 Elasticsearch 请求失败时抛出*/@Overridepublic void indexAccount(Account account) throws IOException {// 创建索引请求并执行IndexResponse createResponse = esClient.index(i -> i.index("accounts") // 指定索引名称.id(account.getId()) // 文档 ID, 使用 account.getId() 获取文档的唯一标识.document(account) // 文档内容);log.info("Document indexed with ID:{}", createResponse.id());}/*** 批量将多个 Account 对象索引到 Elasticsearch 中。** @param accounts 需要索引的账户对象列表* @throws IOException 当 Elasticsearch 请求失败时抛出*/@Overridepublic void indexMultipleAccounts(List<Account> accounts) throws IOException {// 创建批量请求构建器BulkRequest.Builder bulkRequest = new BulkRequest.Builder();// 循环添加每个账户对象的索引请求for (Account account : accounts) {bulkRequest.operations(op -> op.index(idx -> idx.index("accounts").id(account.getId()).document(account)));}// 执行批量请求BulkResponse bulkResponse = esClient.bulk(bulkRequest.build());// 打印出成功的文档 IDif (bulkResponse.errors()) {log.error("Bulk had errors");for (BulkResponseItem item : bulkResponse.items()) {if (item.error() != null) {log.error(item.error().reason());}}} else {log.info("Bulk indexing completed successfully");}}/*** 根据账户编号搜索账户信息。** @param accountNumber 账户编号* @return 匹配的账户信息,以字符串形式返回* @throws IOException 当 Elasticsearch 请求失败时抛出*/@Overridepublic String searchAccountByAccountNumber(Long accountNumber) throws IOException {// 使用 Elasticsearch 客户端进行搜索SearchResponse<Account> searchResponse = esClient.search(s -> s.index("accounts") // 指定索引名称.query(q -> q.term(t -> t.field("account_number") // 搜索字段.value(v -> v.longValue(accountNumber)) // 动态传入搜索值)),Account.class);// 获取总命中数TotalHits totalHits = searchResponse.hits().total();boolean isExactResult = totalHits.relation() == TotalHitsRelation.Eq;if (isExactResult) {log.info("Found exactly " + totalHits.value() + " matching account(s).");} else {log.info("Found more than " + totalHits.value() + " matching account(s).");}// 构建返回结果StringBuilder resultBuilder = new StringBuilder("Search results:\n");for (Hit<Account> hit : searchResponse.hits().hits()) {Account foundAccount = hit.source(); // 获取匹配到的账户信息if (foundAccount != null) {resultBuilder.append(String.format("Account: %s, Name: %s %s\n",foundAccount.getAccountNumber(),foundAccount.getFirstname(),foundAccount.getLastname()));}}// 返回结果if (resultBuilder.length() == 0) {return "No matching accounts found for account number: " + accountNumber;}return resultBuilder.toString();}/*** 根据账户 ID 从 Elasticsearch 获取账户信息。** @param id 账户 ID, 也是文档的唯一标识* @return 对应账户的详细信息* @throws IOException 当 Elasticsearch 请求失败时抛出*/@Overridepublic String searchAccountById(String id) throws IOException {// 创建查询请求GetResponse<Account> response = esClient.get(g -> g.index("accounts").id(id),Account.class);// 判断是否找到对应的账户if (response.found()) {// 获取账户信息Account account = response.source();// 将账户信息转换为 JSON 字符串并返回ObjectMapper mapper = new ObjectMapper();return mapper.writeValueAsString(account);}else {return "Account not found";}}/*** 根据 firstname 和 age 查询账户。** @param firstName 姓名* @param age 年龄* @throws IOException 当 Elasticsearch 请求失败时抛出*/@Overridepublic void searchByNameAndAge(String firstName, int age) throws IOException {// 创建查询条件Query firstNameQuery = MatchQuery.of(m -> m.field("firstname").query(firstName))._toQuery();Query ageQuery = MatchQuery.of(m -> m.field("age").query(age))._toQuery();// 使用 bool 查询将多个条件组合起来BoolQuery boolQuery = BoolQuery.of(b -> b.must(firstNameQuery).must(ageQuery));// 创建搜索请求SearchRequest searchRequest = SearchRequest.of(builder -> builder.index("accounts").query(q -> q.bool(boolQuery)));// 执行查询SearchResponse<Account> searchResponse = esClient.search(searchRequest, Account.class);// 打印结果System.out.println("Search results:");for (Hit<Account> hit : searchResponse.hits().hits()) {System.out.println("Found account: " + hit.source());}}/*** 根据账户 ID 更新账户信息。** @param account 要更新的账户信息* @return 返回更新结果信息* @throws IOException 当 Elasticsearch 请求失败时抛出*/@Overridepublic String updateAccountById(Account account) throws IOException {// 创建更新请求UpdateRequest<Account, Account> updateRequest = UpdateRequest.of(builder -> builder.index("accounts").id(account.getId()).doc(account));// 执行更新操作UpdateResponse<Account> updateResponse = esClient.update(updateRequest, Account.class);// 根据更新结果构建响应信息return "Document updated with result: " + updateResponse.result();}/*** 根据账户 ID 从 Elasticsearch 中删除账户信息。** @param accountId 要删除的账户 ID* @return 返回删除结果信息* @throws IOException 当 Elasticsearch 请求失败时抛出*/@Overridepublic String deleteAccountById(String accountId) throws IOException {// 创建删除请求DeleteRequest deleteRequest = DeleteRequest.of(builder -> builder.index("accounts") // 指定索引.id(accountId) // 指定文档 ID);// 执行删除操作DeleteResponse deleteResponse = esClient.delete(deleteRequest);// 根据删除结果构建响应信息return "Document deleted with result: " + deleteResponse.result();}}
三、测试项目
3.1 添加数据
具体测试代码为:
@SpringBootTest
class AccountElasticsearchServiceImplTest {@Autowiredprivate AccountElasticsearchService accountElasticsearchService;@Testvoid indexAccount() throws IOException {// 创建测试数据Account account = new Account();account.setId("12345");account.setAccountNumber(12345L);account.setEmail("john.doe@example.com");// 调用 indexAccount 方法accountElasticsearchService.indexAccount(account);}
}
运行结果为:
2024-12-07T13:10:42.684+08:00 TRACE 3592 --- [elasticsearch-client] [ main] tracer : curl -iX PUT 'http://localhost:9200/accounts/_doc/12345' -d '{"id":"12345","email":"john.doe@example.com","account_number":12345}'
# HTTP/1.1 201 Created
# Location: /accounts/_doc/12345
# X-elastic-product: Elasticsearch
# content-type: application/json; charset=UTF-8
# content-length: 160
#
# {"_index":"accounts","_type":"_doc","_id":"12345","_version":1,"result":"created","_shards":{"total":2,"successful":1,"failed":0},"_seq_no":4,"_primary_term":1}
2024-12-07T13:10:42.714+08:00 INFO 3592 --- [elasticsearch-client] [ main] .e.c.s.i.AccountElasticsearchServiceImpl : Document indexed with ID:12345
3.2 搜索数据
具体测试代码为:
@SpringBootTest
class AccountElasticsearchServiceImplTest {@Autowiredprivate AccountElasticsearchService accountElasticsearchService;@Testvoid searchAccountByAccountNumber() throws IOException {String result = accountElasticsearchService.searchAccountByAccountNumber(12345L);System.out.println(result);}}
运行结果为:
2024-12-07T13:11:14.508+08:00 TRACE 34672 --- [elasticsearch-client] [ main] tracer : curl -iX POST 'http://localhost:9200/accounts/_search?typed_keys=true' -d '{"query":{"term":{"account_number":{"value":12345}}}}'
# HTTP/1.1 200 OK
# X-elastic-product: Elasticsearch
# content-type: application/json; charset=UTF-8
# content-length: 303
#
# {"took":711,"timed_out":false,"_shards":{"total":1,"successful":1,"skipped":0,"failed":0},"hits":{"total":{"value":1,"relation":"eq"},"max_score":1.0,"hits":[{"_index":"accounts","_type":"_doc","_id":"12345","_score":1.0,"_source":{"id":"12345","email":"john.doe@example.com","account_number":12345}}]}}
2024-12-07T13:11:14.718+08:00 INFO 34672 --- [elasticsearch-client] [ main] .e.c.s.i.AccountElasticsearchServiceImpl : Found exactly 1 matching account(s).
Search results:
Account: 12345, Name: null null
3.3 更新数据
具体测试代码为:
@SpringBootTest
class AccountElasticsearchServiceImplTest {@Autowiredprivate AccountElasticsearchService accountElasticsearchService;@Testvoid searchAccountByAccountNumber() throws IOException {String result = accountElasticsearchService.searchAccountByAccountNumber(12345L);System.out.println(result);}}
运行结果为:
2024-12-07T13:12:56.867+08:00 TRACE 11832 --- [elasticsearch-client] [ main] tracer : curl -iX POST 'http://localhost:9200/accounts/_update/12345' -d '{"doc":{"id":"12345","email":"john.doe@example.com","firstname":"John","lastname":"Doe","account_number":12345}}'
# HTTP/1.1 200 OK
# X-elastic-product: Elasticsearch
# content-type: application/json; charset=UTF-8
# content-length: 160
#
# {"_index":"accounts","_type":"_doc","_id":"12345","_version":2,"result":"updated","_shards":{"total":2,"successful":1,"failed":0},"_seq_no":5,"_primary_term":1}
Document updated with result: Updated
3.4 删除数据
具体测试代码为:
@SpringBootTest
class AccountElasticsearchServiceImplTest {@Autowiredprivate AccountElasticsearchService accountElasticsearchService;@Testvoid deleteAccountById() {try {String result = accountElasticsearchService.deleteAccountById("12345L");System.out.println(result);} catch (IOException e) {e.printStackTrace();}}}
运行结果为:
2024-12-07T13:15:10.064+08:00 TRACE 13804 --- [elasticsearch-client] [ main] tracer : curl -iX DELETE 'http://localhost:9200/accounts/_doc/12345'
# HTTP/1.1 200 OK
# X-elastic-product: Elasticsearch
# content-type: application/json; charset=UTF-8
# content-length: 160
#
# {"_index":"accounts","_type":"_doc","_id":"12345","_version":3,"result":"deleted","_shards":{"total":2,"successful":1,"failed":0},"_seq_no":6,"_primary_term":1}
Document deleted with result: Deleted
参考资料
Connecting | Elasticsearch Java API Client 7.17
ElasticSearch8 - SpringBoot整合ElasticSearch - 王谷雨 - 博客园
相关文章:
【Elasticsearch 中间件】Elasticsearch 客户端使用案例
文章目录 一、安装 Elasticsearch1.1 启动 Elasticsearch1.2 启动 Kibana 二、客户端代码2.1 导入依赖2.2 配置 application.yaml2.3 定义实体类2.4 连接 Elasticserach2.5 定义 Service 层接口2.6 实现 Service 层功能 三、测试项目3.1 添加数据3.2 搜索数据3.3 更新数据3.4 删…...
深入理解MySQL中的ONLY_FULL_GROUP_BY
在MySQL数据库管理中,ONLY_FULL_GROUP_BY是一个重要的SQL模式,它直接影响着GROUP BY语句的执行方式和结果。本文将从基础概念出发,逐步解析ONLY_FULL_GROUP_BY的工作原理、应用场景及应对策略。 什么是ONLY_FULL_GROUP_BY? ONLY…...
获得日志记录之外的新视角:应用程序性能监控简介(APM)
作者:来自 Elastic David Hope 日志记录领域即将发生改变。在这篇文章中,我们将概述从单纯的日志记录到包含日志、跟踪和 APM 的完全集成解决方案的推荐流程。 通过 APM 和跟踪优先考虑客户体验 企业软件开发和运营已成为一个有趣的领域。我们拥有一些非…...
如何避免缓存击穿?超融合常驻缓存和多存储池方案对比
作者:SmartX 解决方案专家 钟锦锌 很多运维人员都知道,混合存储介质配置可能会带来“缓存击穿”的问题,尤其是大数据分析、数据仓库等需要频繁访问“冷数据”的应用场景,缓存击穿可能会更频繁地出现,影响业务运行。除…...
口语笔记——祈使句用法
省略主语 (You give me) a cup of tea, please. 一杯茶(You wait for) another minute. 两等一分钟(You) keep quiet. 保持安静give me a break. 饶了我吧take your hand off. 把你的手拿开take this thing away 把这东西拿开never talk to strangers. 永远不要跟陌生人说话Do…...
SQL连续登录问题(详细案例分析)
如果要统计用户活跃度,那就涉及连续登录问题,接下来将举一个简单的例子来详细说明这个问题: 一、创建一些模拟数据 一些测试数据如下: deviceid1,2022-10-26,2022-10-26,2022-11-01 deviceid1,2022-10-26,2022-11-03,2022-11-0…...
Next.js 系统性教学:深入理解缓存与数据优化策略
更多有关Next.js教程,请查阅: 【目录】Next.js 独立开发系列教程-CSDN博客 目录 前言 1. 缓存的基本概念 1.1 缓存的作用 1.2 Next.js 中的缓存策略 2. Next.js 的缓存机制 2.1 请求记忆化(Request Memoization) 2.1.1 什…...
【PyTorch】(基础六)---- 搭建卷积神经网络
关于神经网络中激活函数、卷积层、池化层等底层原理,我不会在本文中详解,但是关于pytorch中如何使用对应的方法实现这些层的功能我会进行解释,如果你想要了解一些关于神经网络底层的知识,我十分推荐你去看一下吴恩达老师的深度学习…...
【JAVA项目】基于ssm的【美食推荐管理系统】
【JAVA项目】基于ssm的【美食推荐管理系统】 技术简介:采用JSP技术、B/S架构、SSM框架、MySQL技术等实现。 系统简介:美食推荐管理系统,在系统首页可以查看首页、热门美食、美食教程、美食店铺、美食社区、美食资讯、我的、跳转到后台等内容。…...
adb 常用命令笔记
adb connect <ip> #连接指定ip adb disconnect <ip> #断开连接指定ip adb devices #查看连接中的设备 adb install <flie> #安装apk adb uninstall <packageName> #卸载app adb -s install <flie> #指定设备安装 adb shell pm list package…...
[代码随想录Day32打卡] 理论基础 509. 斐波那契数 70. 爬楼梯 746. 使用最小花费爬楼梯
理论基础 题型 动归基础(这一节就是基础题)背包问题打家劫舍股票问题子序列问题 动态规划五部曲 确定dp数组及其下标的含义确定递推公式dp数组如何初始化遍历顺序打印dp数组 509. 斐波那契数 简单~ dp数组及下标含义: dp[i]表示第i各斐…...
android NumberPicker隐藏分割线或修改颜色
在 Android 中,可以通过以下几种方法隐藏 NumberPicker 的分割线: 使用 XML 属性设置 在布局文件中的 NumberPicker 标签内添加 android:selectionDividerHeight"0dp" 属性,将分割线的高度设置为 0,从而达到隐藏分割线…...
7-2 二分查找
输入n值(1<n<1000)、n个非降序排列的整数以及要查找的数x,使用二分查找算法查找x,输出x所在的下标(0~n-1)及比较次数。若x不存在,输出-1和比较次数。 输入格式: 输入共三行: 第一行是n值࿱…...
mid360使用cartorapher进行3d建图导航
1. 添加urdf配置文件: 添加IMU配置关节点和laser关节点 <!-- imu livox --> <joint name"livox_frame_joint" type"fixed"> <parent link"base_link" /> <child link"livox_frame" /> <o…...
Ubuntu安装grafana
需求背景:管理服务器,并在线预警,通知 需求目的: 及时获取服务器状态 技能要求: 1、ubuntu 2、grafana 3、prometheus 4、node 步骤: 一、grafana安装 1、准备系统环境,配置号网络 2、…...
Java版-图论-最短路-Floyd算法
实现描述 网络延迟时间示例 根据上面提示,可以计算出,最大有100个点,最大耗时为100*wi,即最大的耗时为10000,任何耗时计算出来超过这个值可以理解为不可达了;从而得出实现代码里面的: int maxTime 10005…...
可视化建模以及UML期末复习篇----UML图
这是一篇相对较长的文章,如你们所见,比较详细,全长两万字。我不建议你们一次性看完,直接跳目录找你需要的知识点即可。 --------欢迎各位来到我UML国! 一、UML图 总共有如下几种: 用例图(Use Ca…...
HTML常见标签列表,涵盖了多种用途的标签。
文档结构标签 <!DOCTYPE html>:声明文档类型,告诉浏览器使用HTML5标准。<html>:HTML文档的根元素。<head>:包含文档的元数据(meta-data),如标题、字符集、样式表链接、脚本等…...
FPGA 16 ,Verilog中的位宽:深入理解与应用
目录 前言 一. 位宽的基本概念 二. 位宽的定义方法 1. 使用向量变量定义位宽 ① 向量类型及位宽指定 ② 位宽范围及位索引含义 ③ 存储数据与字节数据 2. 使用常量参数定义位宽 3. 使用宏定义位宽 4. 使用[:][-:]操作符定义位宽 1. 详细解释 : 操作符 -: 操作符 …...
vue-生命周期
Vue 的生命周期是指 Vue 实例从创建到销毁期间经历的一系列阶段。每个阶段都有相应的钩子函数(Lifecycle Hooks),允许开发者在这些关键时刻执行自定义逻辑。 一、钩子函数 1. 创建阶段 beforeCreate 在实例初始化之后,数据观测 …...
Linux链表操作全解析
Linux C语言链表深度解析与实战技巧 一、链表基础概念与内核链表优势1.1 为什么使用链表?1.2 Linux 内核链表与用户态链表的区别 二、内核链表结构与宏解析常用宏/函数 三、内核链表的优点四、用户态链表示例五、双向循环链表在内核中的实现优势5.1 插入效率5.2 安全…...
【SQL学习笔记1】增删改查+多表连接全解析(内附SQL免费在线练习工具)
可以使用Sqliteviz这个网站免费编写sql语句,它能够让用户直接在浏览器内练习SQL的语法,不需要安装任何软件。 链接如下: sqliteviz 注意: 在转写SQL语法时,关键字之间有一个特定的顺序,这个顺序会影响到…...
鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院查看报告小程序
一、开发环境准备 工具安装: 下载安装DevEco Studio 4.0(支持HarmonyOS 5)配置HarmonyOS SDK 5.0确保Node.js版本≥14 项目初始化: ohpm init harmony/hospital-report-app 二、核心功能模块实现 1. 报告列表…...
从零开始打造 OpenSTLinux 6.6 Yocto 系统(基于STM32CubeMX)(九)
设备树移植 和uboot设备树修改的内容同步到kernel将设备树stm32mp157d-stm32mp157daa1-mx.dts复制到内核源码目录下 源码修改及编译 修改arch/arm/boot/dts/st/Makefile,新增设备树编译 stm32mp157f-ev1-m4-examples.dtb \stm32mp157d-stm32mp157daa1-mx.dtb修改…...
【单片机期末】单片机系统设计
主要内容:系统状态机,系统时基,系统需求分析,系统构建,系统状态流图 一、题目要求 二、绘制系统状态流图 题目:根据上述描述绘制系统状态流图,注明状态转移条件及方向。 三、利用定时器产生时…...
C++ 求圆面积的程序(Program to find area of a circle)
给定半径r,求圆的面积。圆的面积应精确到小数点后5位。 例子: 输入:r 5 输出:78.53982 解释:由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982,因为我们只保留小数点后 5 位数字。 输…...
QT: `long long` 类型转换为 `QString` 2025.6.5
在 Qt 中,将 long long 类型转换为 QString 可以通过以下两种常用方法实现: 方法 1:使用 QString::number() 直接调用 QString 的静态方法 number(),将数值转换为字符串: long long value 1234567890123456789LL; …...
Redis数据倾斜问题解决
Redis 数据倾斜问题解析与解决方案 什么是 Redis 数据倾斜 Redis 数据倾斜指的是在 Redis 集群中,部分节点存储的数据量或访问量远高于其他节点,导致这些节点负载过高,影响整体性能。 数据倾斜的主要表现 部分节点内存使用率远高于其他节…...
selenium学习实战【Python爬虫】
selenium学习实战【Python爬虫】 文章目录 selenium学习实战【Python爬虫】一、声明二、学习目标三、安装依赖3.1 安装selenium库3.2 安装浏览器驱动3.2.1 查看Edge版本3.2.2 驱动安装 四、代码讲解4.1 配置浏览器4.2 加载更多4.3 寻找内容4.4 完整代码 五、报告文件爬取5.1 提…...
稳定币的深度剖析与展望
一、引言 在当今数字化浪潮席卷全球的时代,加密货币作为一种新兴的金融现象,正以前所未有的速度改变着我们对传统货币和金融体系的认知。然而,加密货币市场的高度波动性却成为了其广泛应用和普及的一大障碍。在这样的背景下,稳定…...
