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 通过应用程序的句柄来注册一个唯一…...
三维GIS开发cesium智慧地铁教程(5)Cesium相机控制
一、环境搭建 <script src"../cesium1.99/Build/Cesium/Cesium.js"></script> <link rel"stylesheet" href"../cesium1.99/Build/Cesium/Widgets/widgets.css"> 关键配置点: 路径验证:确保相对路径.…...
Vue2 第一节_Vue2上手_插值表达式{{}}_访问数据和修改数据_Vue开发者工具
文章目录 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染2. 插值表达式{{}}3. 访问数据和修改数据4. vue响应式5. Vue开发者工具--方便调试 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染 准备容器引包创建Vue实例 new Vue()指定配置项 ->渲染数据 准备一个容器,例如: …...
如何为服务器生成TLS证书
TLS(Transport Layer Security)证书是确保网络通信安全的重要手段,它通过加密技术保护传输的数据不被窃听和篡改。在服务器上配置TLS证书,可以使用户通过HTTPS协议安全地访问您的网站。本文将详细介绍如何在服务器上生成一个TLS证…...
工业自动化时代的精准装配革新:迁移科技3D视觉系统如何重塑机器人定位装配
AI3D视觉的工业赋能者 迁移科技成立于2017年,作为行业领先的3D工业相机及视觉系统供应商,累计完成数亿元融资。其核心技术覆盖硬件设计、算法优化及软件集成,通过稳定、易用、高回报的AI3D视觉系统,为汽车、新能源、金属制造等行…...
自然语言处理——Transformer
自然语言处理——Transformer 自注意力机制多头注意力机制Transformer 虽然循环神经网络可以对具有序列特性的数据非常有效,它能挖掘数据中的时序信息以及语义信息,但是它有一个很大的缺陷——很难并行化。 我们可以考虑用CNN来替代RNN,但是…...
LeetCode - 199. 二叉树的右视图
题目 199. 二叉树的右视图 - 力扣(LeetCode) 思路 右视图是指从树的右侧看,对于每一层,只能看到该层最右边的节点。实现思路是: 使用深度优先搜索(DFS)按照"根-右-左"的顺序遍历树记录每个节点的深度对于…...
回溯算法学习
一、电话号码的字母组合 import java.util.ArrayList; import java.util.List;import javax.management.loading.PrivateClassLoader;public class letterCombinations {private static final String[] KEYPAD {"", //0"", //1"abc", //2"…...
【Go语言基础【13】】函数、闭包、方法
文章目录 零、概述一、函数基础1、函数基础概念2、参数传递机制3、返回值特性3.1. 多返回值3.2. 命名返回值3.3. 错误处理 二、函数类型与高阶函数1. 函数类型定义2. 高阶函数(函数作为参数、返回值) 三、匿名函数与闭包1. 匿名函数(Lambda函…...
七、数据库的完整性
七、数据库的完整性 主要内容 7.1 数据库的完整性概述 7.2 实体完整性 7.3 参照完整性 7.4 用户定义的完整性 7.5 触发器 7.6 SQL Server中数据库完整性的实现 7.7 小结 7.1 数据库的完整性概述 数据库完整性的含义 正确性 指数据的合法性 有效性 指数据是否属于所定…...
逻辑回归暴力训练预测金融欺诈
简述 「使用逻辑回归暴力预测金融欺诈,并不断增加特征维度持续测试」的做法,体现了一种逐步建模与迭代验证的实验思路,在金融欺诈检测中非常有价值,本文作为一篇回顾性记录了早年间公司给某行做反欺诈预测用到的技术和思路。百度…...
