SpringBoot整合Canal实现MySQL与ES数据同步
文章目录
- SpringBoot项目
- 引入Canal依赖
- 配置文件
- 项目结构
- 设置监听类
- 其余类、接口内容
- 启动类
- 实体类
- Controller类
- Mapper接口
- Serice接口
- 运行
- 测试
开始之前请确认docker中已运行mysql与canal容器,并完成了监听binlog配置
未完成可移步: Docker部署Canal监听MySQL的binlog
SpringBoot项目
本次在SpringBoot整合Easy-ES实现对ES的基础操作项目基础上进行操作
此部分操作请移步:SpringBoot整合Easy-ES实现对ES操作
引入Canal依赖
<dependency><groupId>top.javatool</groupId><artifactId>canal-spring-boot-starter</artifactId><version>1.2.1-RELEASE</version></dependency>
配置文件
新增以下内容
注意修改server,换成自己的canal地址,端口号
canal:server: canal地址:11111destination: example
项目结构
设置监听类
CanalTable注解是监听的表名,实现EntryHandler接口
重写监听到mysql增删改操作时,这里的进行自定义操作,方法也都是通过Easy-ES实现
@CanalTable("document")
@Component
public class DocumentHandler implements EntryHandler<Document> {@Resourceprivate IDocumentService documentService;/*** mysql中数据有新增时自动执行* @param document 新增的数据*/@Overridepublic void insert(Document document) {try {documentService.addData(document);} catch (Exception e) {e.printStackTrace();}}/*** mysql中数据有修改时自动执行* @param before 修改前的数据* @param after 修改后的数据*/@Overridepublic void update(Document before, Document after) {documentService.updateData(after);}/*** mysql中数据有删除时自动执行* @param document 要删除的数据*/@Overridepublic void delete(Document document) {documentService.deleteData(document);}
}
其余类、接口内容
启动类
添加扫描ESMapper的注解,指定路径
@EsMapperScan("com.mine.easyEs.mapper")
实体类
@Data
public class Document {@Id/*** es中的唯一id*/private String id;/*** 文档标题*/private String title;/*** 文档内容*/private String content;/*** 创建时间*/private Date createTime;
}
Controller类
包括对索引操作和对数据进行操作的接口
@RestController
@RequestMapping("/ee")
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class DocumentController {private final IDocumentService documentService;/*** 创建索引* @return 结果信息* @throws Exception*/@GetMapping("/createIndex")public String createIndex() throws Exception {return documentService.createIndex();}/*** 删除索引* @return 结果信息*/@GetMapping("/deleteIndex")public String deleteIndex(){return documentService.deleteIndex();}/*** 查询ES所有数据* @return 查询Document结果对象集合*/@GetMapping("/findAll")public List<Document> findAll(){return documentService.findAllData();}/*** ES新增数据* @param document 新增数据对象* @return 结果信息* @throws Exception*/@GetMapping("/add")public String addData(Document document) throws Exception {return documentService.addData(document);}/*** 修改ES数据* @param document 修改数据对象*/@GetMapping("/update")public String updateData(Document document){return documentService.updateData(document);}/*** 根据id删除ES数据* @param id 需要删除的数据的id* @return*/@GetMapping("/delete")public String deleteData(String id){return documentService.deleteDataById(id);}/*** 分词匹配查询content字段* @param value 查询内容* @return*/@GetMapping("/match")public List<Document> findMatch(String value){return documentService.findMatch(value);}}
Mapper接口
继承BaseMapper,整体操作都与MybatisPlus类似
public interface DocumentMapper extends BaseEsMapper<Document> {
}
Serice接口
public interface IDocumentService {/*** 查询ES所有数据* @return 查询Document结果对象集合*/List<Document> findAllData();/*** 创建索引* @return 结果信息* @throws Exception*/String createIndex() throws Exception;/*** 删除索引* @return 结果信息*/String deleteIndex();/*** ES新增数据* @param document 新增数据实体类* @return 结果信息* @throws Exception*/String addData(Document document) throws Exception;/*** 根据id删除ES数据* @param id 需要删除的数据的id* @return*/String deleteDataById(String id);String deleteData(Document document);/*** 修改ES数据* @param document 修改数据对象*/String updateData(Document document);/*** 分词匹配查询content字段* @param value 查询内容* @return*/List<Document> findMatch(String value);
}
Service实现类
@Service
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class DocumentServiceImpl implements IDocumentService {private final DocumentMapper documentMapper;/*** 查询ES所有数据* @return 查询Document结果对象集合*/@Overridepublic List<Document> findAllData() {LambdaEsQueryWrapper<Document> wrapper = new LambdaEsQueryWrapper<>();wrapper.matchAllQuery();return documentMapper.selectList(wrapper);}/*** 创建索引* @return 结果信息* @throws Exception*/@Overridepublic String createIndex() throws Exception {StringBuilder msg = new StringBuilder();String indexName = Document.class.getSimpleName().toLowerCase();boolean existsIndex = documentMapper.existsIndex(indexName);if (existsIndex){throw new Exception("Document实体对应索引已存在,删除索引接口:deleteIndex");}boolean success = documentMapper.createIndex();if (success){msg.append("Document索引创建成功");}else {msg.append("索引创建失败");}return msg.toString();}/*** 删除索引* @return 结果信息*/@Overridepublic String deleteIndex() {StringBuilder msg = new StringBuilder();String indexName = Document.class.getSimpleName().toLowerCase();if (documentMapper.deleteIndex(indexName)){msg.append("删除成功");}else {msg.append("删除失败");}return msg.toString();}/*** ES新增数据* @param document 新增数据实体类* @return 结果信息* @throws Exception*/@Overridepublic String addData(Document document) throws Exception {if (StringUtils.isEmpty(document.getTitle()) || StringUtils.isEmpty(document.getContent())) {throw new Exception("请补全title及content数据");}document.setCreateTime(new Date());documentMapper.insert(document);return "Added successfully!";}/*** 根据id删除ES数据* @param id 需要删除的数据的id* @return*/@Overridepublic String deleteDataById(String id) {documentMapper.deleteById(id);return "Success";}@Overridepublic String deleteData(Document document) {documentMapper.deleteById(document.getId());return "Success";}/*** 修改ES数据* @param document 修改数据对象*/@Overridepublic String updateData(Document document) {documentMapper.updateById(document);return "Success";}/*** 分词匹配查询content字段* @param value 查询内容* @return*/@Overridepublic List<Document> findMatch(String value) {LambdaEsQueryWrapper<Document> wrapper = new LambdaEsQueryWrapper<>();wrapper.match(Document::getContent,value);wrapper.orderByDesc(Document::getCreateTime);List<Document> documents = documentMapper.selectList(wrapper);return documents;}
}
运行
可以看到,正在监听,只不过目前我们没有对数据库进行操作。
测试
我们在数据库新增一条数据
此时插入的这条数据被监听到了
通过测试方法查看ES中是否插入了这条数据
@Testpublic void testSelect() {// 测试查询String title = "3";Document document = EsWrappers.lambdaChainQuery(documentMapper).eq(Document::getTitle, title).one();System.out.println(document);Assertions.assertEquals(title,document.getTitle());}
查到了在mysql新插入的这条数据
数据同步成功
相关文章:

SpringBoot整合Canal实现MySQL与ES数据同步
文章目录 SpringBoot项目引入Canal依赖配置文件项目结构设置监听类其余类、接口内容启动类实体类Controller类Mapper接口Serice接口 运行测试 开始之前请确认docker中已运行mysql与canal容器,并完成了监听binlog配置 未完成可移步: Docker部署Canal监听…...

Zookeeper 源码分析流程
文章目录 前言Zookeeper启动加载磁盘数据与客户端的通信交互Leader选举准备节点状态处理总结 前言 Zookeeper 作为分布式协调服务为分布式系统提供了一些基础服务,如:命名服务、配置管理、同步等,使得开发者可以更加轻松地处理分布式问题。 …...

计数排序与基数排序
计数排序与基数排序 计数排序 计数排序:使用一个数组记录序列中每一个数字出现的次数,将该数组的下标作为实际数据,元素的值作为数据出现的次数。例如对于序列[3,0,1,1,3,3,0,2],统计的结果为: 0出现的次数…...
Mysql—表操作
目录 1、linux中数据库表名区分大小写,windows不区分2、创建数据库表3、外键4、查看数据表结构5、修改表5.1、修改表名5.2、添加字段5.3、指定位置添加字段5.4、修改字段名称5.5、修改字段类型5.6、修改字段位置5.7、删除字段5.8、修改表存储引擎5.9、删除外键 1、l…...

SpringCloud——微服务
微服务技术栈 在之前的开发过程中,我们将所有的服务都部署在一台服务器中,当我们的服务开始越来越多,业务越来越复杂,当一台服务器不能承担我们的业务的时候,就需要将不同的业务分开部署在不同的服务器上,…...

深入理解Java单例模式和优化多线程任务处理
目录 饿汉模式懒汉模式单线程版多线程版双重检查锁定 阻塞队列 单例模式能保证某个类在程序中只存在唯一一份实例, 而不会创建出多个实例,并提供一个全局访问点。 饿汉模式 类加载的同时,创建实例。 class Singleton {private static final Singlet…...

已解决 Kotlin Error: Type mismatch: inferred type is String but Int was expected
🌷🍁 博主猫头虎(🐅🐾)带您 Go to New World✨🍁 🦄 博客首页: 🐅🐾猫头虎的博客🎐《面试题大全专栏》 🦕 文章图文并茂🦖…...

Web应用系统的小安全漏洞及相应的攻击方式
写作目的 本文讲述一个简单的利用WebAPI来进行一次基本没有破坏力的“黑客”行为。 主要目的如下: 了解什么叫安全漏洞 知道什么是api 了解一些获取api的工具 通过对API的认识了解白盒接口测试基本概念和技术 免责声明: 本文主要是以学习交流为目的&a…...

git工具下载和安装
(1)从git官网下载安装包 然后安装 https://git-scm.com/downloads (2)git 学习参考官方的资料 https://git-scm.com/book/en/v2...

腾讯mini项目-【指标监控服务重构】2023-08-04
今日已办 关于 span-references 的调研 https://github.com/DataDog/dd-trace-js/issues/1761 https://github.com/open-telemetry/opentelemetry-specification/blob/874a451e7f6ac7fc54423ee3f03e5394197be35b/specification/compatibility/opentracing.md#span-references h…...

怎么推广自己抖店的商品?最适合0经验新手操作的办法,来看看
我是王路飞。 抖店开通后,想要把自己店铺的商品卖出去,就需要进行推广了。 但是怎么推广呢? 要么利用抖音的搜索和推荐流量,获取曝光,实现点击和转化。 不过这种玩法有个弊端,就是需要你有一定的电商经…...

线性代数的本质(三)——线性方程组
文章目录 线性方程组高斯消元法初等行变换线性方程组的解向量方程齐次线性方程组的解非齐次线性方程组的解 线性方程组 高斯消元法 客观世界最简单的数量关系是均匀变化的关系。在均匀变化问题中,列出的方程组是一次方程组,我们称之为线性方程组(Linea…...

轻量级性能测试工具 wrk 如何使用?
项目设计之初或者是项目快要结束的时候,大佬就会问我们,这个服务性能测试的结果是什么,QPS 可以达到多少,RPS 又能达到多少?接口性能可以满足未来生产环境的实际情况吗?有没有自己测试过自己接口的吞吐量&a…...

WebGL 视图矩阵、模型视图矩阵
目录 立方体由三角形构成 视点和视线 视点、观察目标点和上方向 视点: 观察目标点: 上方向: 在WebGL中,观察者的默认状态应该是这样的: 视图矩阵程序(LookAtTriangles.js) 实际上&…...
Python 3 – 文件 readline() 方法
Python 3 – 文件 readline() 方法|极客笔记 # 打开文件 file open("example.txt", "r")# 读取文件中的一行数据 line file.readline() while line:# 移除行尾的换行符print(line.strip())# 读取文件中的下一行数据line file.readline()# 关闭文件 file…...

如何在微软Edge浏览器上一键观看高清视频?
编者按:视频是当下最流行的媒体形式之一。但由于视频压缩、网络不稳定等原因,我们常常可以看到互联网上的很多视频其画面质量并不理想,尤其是在浏览器端,这极大地影响了观看体验。不过,近期微软 Edge 浏览器推出了一项…...
Telegram BoT的主流项目盘点
目录 DeFi 类 数据分析类 空投埋伏交易 其他 Telegram Bot赛道的发展趋势预测 Telegram BoT赛道发展较快,具体来看可以分为DeFi 类、数据分析类、空投埋伏交易类以及其他。 DeFi 类 Unibot(交易)、Banana Gun、WagieBot(交…...
PTA 甲级 1044 Shopping in Mars
题目链接 思路:前缀和滑动窗口 #include<bits/stdc.h> #define MAXN 100010 using namespace std; int a[MAXN];int main(){int n,m;cin>>n>>m;//n数量 m金额for(int i1;i<n;i){int t;cin>>t;a[i]a[i-1]t;//前缀和}vector<pair<in…...
Linux学习之MyCat实现分库分表
环境准备 先准备一套MySQL主从服务器,可参考MySQL主从配置配置MyCat服务 资源下载 网盘链接: https://pan.baidu.com/s/1cLTMH_e1-6loc_gF9ZNHTg?pwda63n 提取码: a63n MyCat配置 # 1)安装mycat软件 //安装jdk [rootmycat58 upload]# yum -y insta…...

DirectX12(d3d12)初始化
一、前置要求 Windows 10及以上(安装有DirectX12)VisualStudio 2022 二、DirectX12入门 1.引用头文件 #include<Windows.h> #include<d3d12.h> #include<dxgi1_4.h>2.注册窗口类并初始化窗口 这里我们调用Windows API 通过应用程序的句柄来注册一个唯一…...

C++实现分布式网络通信框架RPC(3)--rpc调用端
目录 一、前言 二、UserServiceRpc_Stub 三、 CallMethod方法的重写 头文件 实现 四、rpc调用端的调用 实现 五、 google::protobuf::RpcController *controller 头文件 实现 六、总结 一、前言 在前边的文章中,我们已经大致实现了rpc服务端的各项功能代…...
利用ngx_stream_return_module构建简易 TCP/UDP 响应网关
一、模块概述 ngx_stream_return_module 提供了一个极简的指令: return <value>;在收到客户端连接后,立即将 <value> 写回并关闭连接。<value> 支持内嵌文本和内置变量(如 $time_iso8601、$remote_addr 等)&a…...

css实现圆环展示百分比,根据值动态展示所占比例
代码如下 <view class""><view class"circle-chart"><view v-if"!!num" class"pie-item" :style"{background: conic-gradient(var(--one-color) 0%,#E9E6F1 ${num}%),}"></view><view v-else …...
QMC5883L的驱动
简介 本篇文章的代码已经上传到了github上面,开源代码 作为一个电子罗盘模块,我们可以通过I2C从中获取偏航角yaw,相对于六轴陀螺仪的yaw,qmc5883l几乎不会零飘并且成本较低。 参考资料 QMC5883L磁场传感器驱动 QMC5883L磁力计…...
uni-app学习笔记二十二---使用vite.config.js全局导入常用依赖
在前面的练习中,每个页面需要使用ref,onShow等生命周期钩子函数时都需要像下面这样导入 import {onMounted, ref} from "vue" 如果不想每个页面都导入,需要使用node.js命令npm安装unplugin-auto-import npm install unplugin-au…...

高频面试之3Zookeeper
高频面试之3Zookeeper 文章目录 高频面试之3Zookeeper3.1 常用命令3.2 选举机制3.3 Zookeeper符合法则中哪两个?3.4 Zookeeper脑裂3.5 Zookeeper用来干嘛了 3.1 常用命令 ls、get、create、delete、deleteall3.2 选举机制 半数机制(过半机制࿰…...

(二)原型模式
原型的功能是将一个已经存在的对象作为源目标,其余对象都是通过这个源目标创建。发挥复制的作用就是原型模式的核心思想。 一、源型模式的定义 原型模式是指第二次创建对象可以通过复制已经存在的原型对象来实现,忽略对象创建过程中的其它细节。 📌 核心特点: 避免重复初…...
python爬虫:Newspaper3k 的详细使用(好用的新闻网站文章抓取和解析的Python库)
更多内容请见: 爬虫和逆向教程-专栏介绍和目录 文章目录 一、Newspaper3k 概述1.1 Newspaper3k 介绍1.2 主要功能1.3 典型应用场景1.4 安装二、基本用法2.2 提取单篇文章的内容2.2 处理多篇文档三、高级选项3.1 自定义配置3.2 分析文章情感四、实战案例4.1 构建新闻摘要聚合器…...

12.找到字符串中所有字母异位词
🧠 题目解析 题目描述: 给定两个字符串 s 和 p,找出 s 中所有 p 的字母异位词的起始索引。 返回的答案以数组形式表示。 字母异位词定义: 若两个字符串包含的字符种类和出现次数完全相同,顺序无所谓,则互为…...
今日科技热点速览
🔥 今日科技热点速览 🎮 任天堂Switch 2 正式发售 任天堂新一代游戏主机 Switch 2 今日正式上线发售,主打更强图形性能与沉浸式体验,支持多模态交互,受到全球玩家热捧 。 🤖 人工智能持续突破 DeepSeek-R1&…...