实战:大数据Flink CDC同步Mysql数据到ElasticSearch

文章目录

    • 前言
    • 知识积累
      • CDC简介
      • CDC的种类
      • 常见的CDC方案比较
    • Springboot接入Flink CDC
      • 环境准备
      • 项目搭建
    • 本地运行
    • 集群运行
      • 将项目打包将包传入集群启动
      • 远程将包部署到flink集群
    • 写在最后

前言

前面的博文我们分享了大数据分布式流处理计算框架Flink和其基础环境的搭建,相信各位看官都已经搭建好了自己的运行环境。那么,今天就来实战一把使用Flink CDC同步Mysql数据导Elasticsearch。

知识积累

CDC简介

CDC 的全称是 Change Data Capture(变更数据捕获技术) ,在广义的概念上,只要是能捕获数据变更的技术,我们都可以称之为 CDC 。目前通常描述的 CDC 技术主要面向数据库的变更,是一种用于捕获数据库中数据变更的技术。
在这里插入图片描述

CDC的种类

CDC 的技术方案非常多,目前业界主流的实现机制可以分为两种:
基于查询的 CDC:
◆离线调度查询作业,批处理。把一张表同步到其他系统,每次通过查询去获取表中最新的数据;
◆无法保障数据一致性,查的过程中有可能数据已经发生了多次变更;
◆不保障实时性,基于离线调度存在天然的延迟。
基于日志的 CDC:
◆实时消费日志,流处理,例如 MySQL 的 binlog 日志完整记录了数据库中的变更,可以把 binlog 文件当作流的数据源;
◆保障数据一致性,因为 binlog 文件包含了所有历史变更明细;
◆保障实时性,因为类似 binlog 的日志文件是可以流式消费的,提供的是实时数据。

常见的CDC方案比较

在这里插入图片描述

Springboot接入Flink CDC

由于Flink官方提供了Java、Scala、Python语言接口用以开发Flink应用程序,故我们可以直接用Maven引入Flink依赖进行功能实现。

环境准备

1、SpringBoot 2.4.3
2、Flink 1.13.6
3、Scala 2.11
4、Maven 3.6.3
5、Java 8
6、mysql 8
7、es 7
Springboot、Flink、Scala版本一定要相匹配,也可以严格按照本博客进行配置。
注意:
如果只是本机测试玩玩,Maven依赖已经整合计算环境,不用额外搭建Flink环境;如果需要部署到Flink集群则需要额外搭建Flink集群。另外Scala 版本只是用于依赖选择,不用关心Scala环境。

项目搭建

1、引入Flink CDC Maven依赖

pom.xml

<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.4.3</version><relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>flink-demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>flink-demo</name>
<description>Demo project for Spring Boot</description>
<properties><java.version>8</java.version><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding><flink.version>1.13.6</flink.version>
</properties>
<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.23</version></dependency><!-- Flink CDC connector for MySQL --><dependency><groupId>com.ververica</groupId><artifactId>flink-connector-mysql-cdc</artifactId><version>2.1.0</version><exclusions><exclusion><groupId>org.apache.flink</groupId><artifactId>flink-shaded-guava</artifactId></exclusion></exclusions></dependency><!-- Flink CDC connector for ES https://mvnrepository.com/artifact/org.apache.flink/flink-connector-elasticsearch7_2.11--><dependency><groupId>org.apache.flink</groupId><artifactId>flink-connector-elasticsearch7_2.11</artifactId><version>${flink.version}</version></dependency><!-- https://mvnrepository.com/artifact/org.apache.flink/flink-json --><dependency><groupId>org.apache.flink</groupId><artifactId>flink-json</artifactId><version>${flink.version}</version></dependency><!-- https://mvnrepository.com/artifact/org.apache.flink/flink-table-api-java-bridge_2.11 --><dependency><groupId>org.apache.flink</groupId><artifactId>flink-table-api-java-bridge_2.11</artifactId><version>${flink.version}</version></dependency><!-- https://mvnrepository.com/artifact/org.apache.flink/flink-table-planner_2.11 --><dependency><groupId>org.apache.flink</groupId><artifactId>flink-table-planner_2.11</artifactId><version>${flink.version}</version></dependency><dependency><groupId>org.apache.flink</groupId><artifactId>flink-table-planner-blink_2.11</artifactId><version>${flink.version}</version></dependency><!-- https://mvnrepository.com/artifact/org.apache.flink/flink-clients_2.11 --><dependency><groupId>org.apache.flink</groupId><artifactId>flink-clients_2.11</artifactId><version>${flink.version}</version></dependency><dependency><groupId>org.apache.flink</groupId><artifactId>flink-java</artifactId><version>${flink.version}</version></dependency><!-- https://mvnrepository.com/artifact/org.apache.flink/flink-streaming-java_2.11 --><dependency><groupId>org.apache.flink</groupId><artifactId>flink-streaming-java_2.11</artifactId><version>${flink.version}</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency>
</dependencies>

2、创建测试数据库表users

users表结构

CREATE TABLE `users` (`id` bigint NOT NULL AUTO_INCREMENT COMMENT 'ID',`name` varchar(50) NOT NULL COMMENT '名称',`birthday` timestamp NULL DEFAULT NULL COMMENT '生日',`ts` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='用户';

3、es索引操作

es操作命令
es索引会自动创建

#设置es分片与副本
curl -X PUT "10.10.22.174:9200/users" -u elastic:VaHcSC3mOFfovLWTqW6E   -H 'Content-Type: application/json' -d'
{"settings" : {"number_of_shards" : 3,"number_of_replicas" : 2}
}'#查询index下全部数据 
curl -X GET "http://10.10.22.174:9200/users/_search"  -u elastic:VaHcSC3mOFfovLWTqW6E -H 'Content-Type: application/json' #删除index
curl -X DELETE "10.10.22.174:9200/users" -u elastic:VaHcSC3mOFfovLWTqW6E

本地运行

@SpringBootTest
class FlinkDemoApplicationTests {/*** flinkCDC* mysql to es* @author senfel* @date 2023/8/22 14:37 * @return void*/@Testvoid flinkCDC() throws Exception{EnvironmentSettings fsSettings = EnvironmentSettings.newInstance()//.useBlinkPlanner().inStreamingMode().build();StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();env.setParallelism(1);StreamTableEnvironment tableEnv = StreamTableEnvironment.create(env,fsSettings);tableEnv.getConfig().setSqlDialect(SqlDialect.DEFAULT);// 数据源表String sourceDDL ="CREATE TABLE users (\n" +"  id BIGINT PRIMARY KEY NOT ENFORCED ,\n" +"  name STRING,\n" +"  birthday TIMESTAMP(3),\n" +"  ts TIMESTAMP(3)\n" +") WITH (\n" +"      'connector' = 'mysql-cdc',\n" +"      'hostname' = '10.10.10.202',\n" +"      'port' = '6456',\n" +"      'username' = 'root',\n" +"      'password' = 'MyNewPass2021',\n" +"      'server-time-zone' = 'Asia/Shanghai',\n" +"      'database-name' = 'cdc',\n" +"      'table-name' = 'users'\n" +"      )";// 输出目标表String sinkDDL ="CREATE TABLE users_sink_es\n" +"(\n" +"    id BIGINT PRIMARY KEY NOT ENFORCED,\n" +"    name STRING,\n" +"    birthday TIMESTAMP(3),\n" +"    ts TIMESTAMP(3)\n" +") \n" +"WITH (\n" +"  'connector' = 'elasticsearch-7',\n" +"  'hosts' = 'http://10.10.22.174:9200',\n" +"  'index' = 'users',\n" +"  'username' = 'elastic',\n" +"  'password' = 'VaHcSC3mOFfovLWTqW6E'\n" +")";// 简单的聚合处理String transformSQL = "INSERT INTO users_sink_es SELECT * FROM users";tableEnv.executeSql(sourceDDL);tableEnv.executeSql(sinkDDL);TableResult result = tableEnv.executeSql(transformSQL);result.print();env.execute("mysql-to-es");}

请求es用户索引发现并无数据:

[root@bluejingyu-1 ~]# curl -X GET “http://10.10.22.174:9200/users/_search” -u elastic:VaHcSC3mOFfovLWTqW6E -H ‘Content-Type: application/json’
{“took”:0,“timed_out”:false,“_shards”:{“total”:3,“successful”:3,“skipped”:0,“failed”:0},“hits”:{“total”:{“value”:0,“relation”:“eq”},“max_score”:null,“hits”:[]}}

操作mysql数据库新增多条数据

5 senfel 2023-08-30 15:02:28 2023-08-30 15:02:36
6 sebfel2 2023-08-30 15:02:43 2023-08-30 15:02:47

再次获取es用户索引查看数据

[root@bluejingyu-1 ~]# curl -X GET “http://10.10.22.174:9200/users/_search” -u elastic:VaHcSC3mOFfovLWTqW6E -H ‘Content-Type: application/json’
{“took”:67,“timed_out”:false,“_shards”:{“total”:3,“successful”:3,“skipped”:0,“failed”:0},“hits”:{“total”:{“value”:2,“relation”:“eq”},“max_score”:1.0,“hits”:[{“_index”:“users”,“_type”:“_doc”,“_id”:“5”,“_score”:1.0,“_source”:{“id”:5,“name”:“senfel”,“birthday”:“2023-08-30 15:02:28”,“ts”:“2023-08-30 15:02:36”}},{“_index”:“users”,“_type”:“_doc”,“_id”:“6”,“_score”:1.0,“_source”:{“id”:6,“name”:“sebfel2”,“birthday”:“2023-08-30 15:02:43”,“ts”:“2023-08-30 15:02:47”}}]}}

由上测试结果可知本地运行无异常。

集群运行

项目树:
在这里插入图片描述

1、创建集群运行代码逻辑

/*** FlinkMysqlToEs* @author senfel* @version 1.0* @date 2023/8/22 14:56*/
public class FlinkMysqlToEs {public static void main(String[] args) throws Exception {EnvironmentSettings fsSettings = EnvironmentSettings.newInstance()//.useBlinkPlanner().inStreamingMode().build();StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();env.setParallelism(1);StreamTableEnvironment tableEnv = StreamTableEnvironment.create(env,fsSettings);tableEnv.getConfig().setSqlDialect(SqlDialect.DEFAULT);// 数据源表String sourceDDL ="CREATE TABLE users (\n" +"  id BIGINT PRIMARY KEY NOT ENFORCED ,\n" +"  name STRING,\n" +"  birthday TIMESTAMP(3),\n" +"  ts TIMESTAMP(3)\n" +") WITH (\n" +"      'connector' = 'mysql-cdc',\n" +"      'hostname' = '10.10.10.202',\n" +"      'port' = '6456',\n" +"      'username' = 'root',\n" +"      'password' = 'MyNewPass2021',\n" +"      'server-time-zone' = 'Asia/Shanghai',\n" +"      'database-name' = 'cdc',\n" +"      'table-name' = 'users'\n" +"      )";// 输出目标表String sinkDDL ="CREATE TABLE users_sink_es\n" +"(\n" +"    id BIGINT PRIMARY KEY NOT ENFORCED,\n" +"    name STRING,\n" +"    birthday TIMESTAMP(3),\n" +"    ts TIMESTAMP(3)\n" +") \n" +"WITH (\n" +"  'connector' = 'elasticsearch-7',\n" +"  'hosts' = 'http://10.10.22.174:9200',\n" +"  'index' = 'users',\n" +"  'username' = 'elastic',\n" +"  'password' = 'VaHcSC3mOFfovLWTqW6E'\n" +")";// 简单的聚合处理String transformSQL = "INSERT INTO users_sink_es SELECT * FROM users";tableEnv.executeSql(sourceDDL);tableEnv.executeSql(sinkDDL);TableResult result = tableEnv.executeSql(transformSQL);result.print();env.execute("mysql-to-es");}
}

2、集群运行需要将Flink程序打包,不同于普通的jar包,这里必须采用shade

<build><finalName>flink-demo</finalName><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-shade-plugin</artifactId><version>3.2.4</version><executions><execution><phase>package</phase><goals><goal>shade</goal></goals><configuration><createDependencyReducedPom>false</createDependencyReducedPom><artifactSet><excludes><exclude>com.google.code.findbugs:jsr305</exclude><exclude>org.slf4j:*</exclude><exclude>log4j:*</exclude></excludes></artifactSet><filters><filter><artifact>*:*</artifact><excludes><exclude>module-info.class</exclude><exclude>META-INF/*.SF</exclude><exclude>META-INF/*.DSA</exclude><exclude>META-INF/*.RSA</exclude></excludes></filter></filters><transformers><transformerimplementation="org.apache.maven.plugins.shade.resource.AppendingTransformer"><resource>META-INF/spring.handlers</resource><resource>reference.conf</resource></transformer><transformerimplementation="org.springframework.boot.maven.PropertiesMergingResourceTransformer"><resource>META-INF/spring.factories</resource></transformer><transformerimplementation="org.apache.maven.plugins.shade.resource.AppendingTransformer"><resource>META-INF/spring.schemas</resource></transformer><transformerimplementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer" /><transformerimplementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"><mainClass>com.example.flinkdemo.FlinkMysqlToEs</mainClass></transformer></transformers></configuration></execution></executions></plugin></plugins>
</build>

将项目打包将包传入集群启动

1、项目打包
mvn package -Dmaven.test.skip=true

2、手动上传到服务器拷贝如集群内部运行:
/opt/flink/bin# ./flink run …/flink-demo.jar

3、测试操作mysql数据库

删除id =6只剩下id=5的用户

5 senfel000 2023-08-30 15:02:28 2023-08-30 15:02:36

4、查询es用户索引

[root@bluejingyu-1 ~]# curl -X GET “http://10.10.22.174:9200/users/_search” -u elastic:VaHcSC3mOFfovLWTqW6E -H ‘Content-Type: application/json’
{“took”:931,“timed_out”:false,“_shards”:{“total”:3,“successful”:3,“skipped”:0,“failed”:0},“hits”:{“total”:{“value”:1,“relation”:“eq”},“max_score”:1.0,“hits”:[{“_index”:“users”,“_type”:“_doc”,“_id”:“5”,“_score”:1.0,“_source”:{“id”:5,“name”:“senfel”,“birthday”:“2023-08-30 15:02:28”,“ts”:“2023-08-30 15:02:36”}}]}}[

如上所示es中只剩下了id==5的数据;
经测试手动部署到集群环境成功。

远程将包部署到flink集群

1、新增controller触发接口

/*** remote runTask* @author senfel* @date 2023/8/30 16:57 * @return org.apache.flink.api.common.JobID*/
@GetMapping("/runTask")
public JobID runTask() {try {// 集群信息Configuration configuration = new Configuration();configuration.setString(JobManagerOptions.ADDRESS, "10.10.22.91");configuration.setInteger(JobManagerOptions.PORT, 6123);configuration.setInteger(RestOptions.PORT, 8081);RestClusterClient<StandaloneClusterId>  client = new RestClusterClient<>(configuration, StandaloneClusterId.getInstance());//jar包存放路径,也可以直接调用hdfs中的jarFile jarFile = new File("input/flink-demo.jar");SavepointRestoreSettings savepointRestoreSettings = SavepointRestoreSettings.none();//构建提交任务参数PackagedProgram program = PackagedProgram.newBuilder().setConfiguration(configuration).setEntryPointClassName("com.example.flinkdemo.FlinkMysqlToEs").setJarFile(jarFile).setSavepointRestoreSettings(savepointRestoreSettings).build();//创建任务JobGraph jobGraph = PackagedProgramUtils.createJobGraph(program, configuration, 1, false);//提交任务CompletableFuture<JobID> result = client.submitJob(jobGraph);return result.get();} catch (Exception e) {e.printStackTrace();return null;}
}

2、启动Springboot项目
在这里插入图片描述

3、postman请求
在这里插入图片描述
4、查看Fink集群控制台
在这里插入图片描述

由上图所示已将远程部署完成。

5、测试操作mysql数据库

5 senfel000 2023-08-30 15:02:28 2023-08-30 15:02:36
7 eeeee 2023-08-30 17:12:00 2023-08-30 17:12:04
8 33333 2023-08-30 17:12:08 2023-08-30 17:12:11

6、查询es用户索引

[root@bluejingyu-1 ~]# curl -X GET “http://10.10.22.174:9200/users/_search” -u elastic:VaHcSC3mOFfovLWTqW6E -H ‘Content-Type: application/json’
{“took”:766,“timed_out”:false,“_shards”:{“total”:3,“successful”:3,“skipped”:0,“failed”:0},“hits”:{“total”:{“value”:3,“relation”:“eq”},“max_score”:1.0,“hits”:[{“_index”:“users”,“_type”:“_doc”,“_id”:“5”,“_score”:1.0,“_source”:{“id”:5,“name”:“senfel000”,“birthday”:“2023-08-30 15:02:28”,“ts”:“2023-08-30 15:02:36”}},{“_index”:“users”,“_type”:“_doc”,“_id”:“7”,“_score”:1.0,“_source”:{“id”:7,“name”:“eeeee”,“birthday”:“2023-08-30 17:12:00”,“ts”:“2023-08-30 17:12:04”}},{“_index”:“users”,“_type”:“_doc”,“_id”:“8”,“_score”:1.0,“_source”:{“id”:8,“name”:“33333”,“birthday”:“2023-08-30 17:12:08”,“ts”:“2023-08-30 17:12:11”}}]}}

如上所以es中新增了两条数据;
经测试远程发布Flink Task完成。

写在最后

大数据Flink CDC同步Mysql数据到ElasticSearch搭建与测试运行较为简单,对于基础的学习测试环境独立集群目前只支持单个任务部署,如果需要多个任务或者运用于生产可以采用Yarn与Job分离模式进行部署。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

第15章_锁: MySQL并发访问相同记录以及从数据操作的类型划分锁(读锁、写锁)

事务的 隔离性 由这章讲述的 锁 来实现。 1. 概述 锁是计算机协调多个进程或线程并发访问某一资源的机制. 在程序开发中会存在多线程同步的问题, 当多个线程并发访问某个数据的时候, 尤其是针对一些敏感数据(订单, 金额), 我们就需要保证这个数据在任何时刻最多只有一个线…

Nginx重写功能和反向代理

目录 一、重写功能rewrite 1.1 if指令 1.2 return 1.3 set指令 1.4 break 指令 二、反向代理 2.1动静分离 2.2 缓存功能 2.3 ip穿透 2.4 http反向代理负载均衡 一、重写功能rewrite Nginx服务器利用 ngx_http_rewrite_module 模块解析和处理rewrite请求&#xff0c;此…

Kafka环境搭建与相关启动命令

一、Kafka环境搭建 点击下载kafka_2.11-2.3.1.tgz文件链接 1、上传kafka_2.11-2.3.1.tgz&#xff0c;解压kafka_2.11-2.3.1.tgz&#xff0c;得到kafka_2.11-2.3.1文件夹 1&#xff09;上传 #使用mobaxterm将 kafka_2.11-2.3.1.tgz 传入tools文件夹 #用下面代码进入tools文件…

【docker】docker的一些常用命令-------从小白到大神之路之学习运维第92天

目录 一、安装docker-ce 1、从阿里云下载docker-cer.epo源 2、下载部分依赖 3、安装docker 二、启用docker 1、启动docker和不启动查看docker version 2、启动服务查看docker version 有什么区别&#xff1f;看到了吗&#xff1f; 3、看看docker启动后的镜像仓库都有什…

异步请求库的实际应用案例:爬取豆瓣经典电影

在日常爬虫过程中&#xff0c;你有没有遇到过需要爬取大量数据的情况&#xff0c;但是传统的同步请求方式让您等得焦头烂额&#xff1f; 这个问题的根源在于传统的同步请求方式。当我们使用同步请求时&#xff0c;程序会一直等待服务器的响应&#xff0c;直到数据返回后才能继续…

如何实现24/7客户服务自动化?

传统的客服制胜与否的法宝在于人&#xff0c;互联网时代&#xff0c;对于产品线广的大型企业来说&#xff1a;单靠人力&#xff0c;成本大且效率低&#xff0c;相对于产品相对单一的中小型企业来说&#xff1a;建设传统客服系统的成本难以承受&#xff0c;企业客户服务的转型已…

GPT转换工具:轻松将MBR转换为GPT磁盘

为什么需要将MBR转换为GPT&#xff1f; 众所周知&#xff0c;Windows 11已经发布很长时间了。在此期间&#xff0c;许多老用户已经从Windows 10升级到Windows 11。但有些用户仍在运行Windows 10。对于那些想要升级到Win 11的用户来说&#xff0c;他们可能不确定Win 11应该使…

Revit SDK 介绍:GenericModelCreation常规模型的创建

前言 这个例子介绍了如何创建拉伸、放样、扫掠、融合、放样融合&#xff0c;涵盖了一个建模软件需要的基本建模方法。 内容 CreateExtrusion 生成的放样融合接口&#xff1a; m_creationFamily.NewExtrusion(true, curve, sketchPlane, bottomProfile, topProfile)核心逻辑&…

Python常用IDE选择与安装

1、IDE简介 选择一款高效而又顺手的IDE学习或使用Python&#xff0c;可以让你的开发之路充满激情和动力&#xff0c;让你真正投入其中。 常见的Python的IDE工具有&#xff1a; PyCharm 由JetBrains开发的Python IDE&#xff0c;功能强大&#xff0c;支持调试、代码自动完成、…

C++数组类的自实现,使其可以保存学生成绩,并进行降序排列

类的封装 #ifndef ARRAY_H #define ARRAY_Hclass DoubArray { private:int m_length;double* m_pointer;public:DoubArray(int len);DoubArray(const DoubArray& obj);int length();bool get(int index, double& value);bool set(int index, double value);void sort(…

OpenCV基本操(IO操作,读取、显示、保存)

图像的IO操作&#xff0c;读取和保存方法 1.1 API cv.imread()参数&#xff1a; 要读取的图像 读取图像的方式&#xff1a; cv.IMREAD*COLOR:以彩色模式加载图像&#xff0c;任何图像的图像的透明度都将被忽略。这是默认参数 标志&#xff1a; 1 cv.IMREAD*GRAYSCALE :以…

47、springboot 的 国际化消息支持--就是根据浏览器选择的语言,项目上的一些提示信息根据语言的选择进行对应的显示

springboot的国际化也是基于spring mvc 的。 springboot 的 国际化消息支持–就是根据浏览器选择的语言&#xff0c;项目上的一些提示信息根据语言的选择进行对应的显示。 总结下国家化自动配置&#xff1a; 功能实现就是&#xff1a; 比如一个登录页面&#xff0c;我们在浏览…

WebServer 解析HTTP 请求报文

一、TCP 状态转换 浏览器访问网址&#xff0c;TCP传输全过程 二、TCP协议的通信过程 三、TCP 通信流程 // TCP 通信的流程 // 服务器端 &#xff08;被动接受连接的角色&#xff09; 1. 创建一个用于监听的套接字- 监听&#xff1a;监听有客户端的连接- 套接字&#xff1a;这…

复制粘贴是怎么实现的

在上面的代码中&#xff0c;command 和 select 是自定义的函数。它们的作用如下&#xff1a; 实现复制粘贴的思路&#xff1a; 创建一个 textarea 标签将 textarea 移出可视区域给这个 textarea 赋值将这个 textarea 标签添加到页面中调用 textarea 的 select 方法调用 docum…

98. 验证二叉搜索树

给你一个二叉树的根节点 root &#xff0c;判断其是否是一个有效的二叉搜索树。 有效 二叉搜索树定义如下&#xff1a; 节点的左子树只包含 小于 当前节点的数。节点的右子树只包含 大于 当前节点的数。所有左子树和右子树自身必须也是二叉搜索树。 示例 1&#xff1a; 输入&am…

【C++基础】类与对象(上):访问限定符、类作用域、类实例化、类对象模型、this指针

​&#x1f47b;内容专栏&#xff1a; C/C编程 &#x1f428;本文概括&#xff1a; C基础语法。访问限定符、类作用域、类实例化、类对象模型、this指针等。 &#x1f43c;本文作者&#xff1a; 阿四啊 &#x1f438;发布时间&#xff1a;2023.9.6 面向过程和面向对象初识 C语…

【图文并茂】C++介绍之串

1.1串 引子—— ​ 字符串简称为串&#xff0c;串是由字符元素构成的&#xff0c;其中元素的逻辑关系也是一种线性关系。串的处理在计算机非数值处理中占用重要的地位&#xff0c;如信息检索系统&#xff0c;文字编辑等都是以串数据作为处理对象 串是由零个或多个字符组成的…

Docker基础入门:Docker基础总结篇--超详细

Docker基础入门&#xff1a;Docker基础总结篇[docker3要素、docker安装配置、容器使用、镜像管理发布] 一、Docker 3要素1.1、镜像&#xff08;Image&#xff09;1.2、容器&#xff08;Container&#xff09;1.3、仓库&#xff08;Registry&#xff09;1.4 、总结 二、Docker安…

Exception_json反序列化失败_JSONException

TokenGroup tokenGroup JSONObject.parseObject(tokenGroup1, TokenGroup.class);com.alibaba.fastjson.JSONException: create instance error, null, public com.daikin.snapshot.controller.auth.token.TokenGroup 解决方法: 在反序列化失败的实体类添加无参构造方法

QT 使用信号与槽实现界面跳转

一、创建一个新的页面 1 > 在原有工程上新建一个页面 2 > 选择Qt - Qt 设计师界面类 - choose 3 > 选择Widget模板 - 下一步 4 > 输入自定义类名 - 下一步 会自动生成其同名的.h .cpp .ui文件 5 > 最终效果 Headers存放.h文件 Soueces存放.cpp文件 Forms存放.u…