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 通过应用程序的句柄来注册一个唯一…...
后进先出(LIFO)详解
LIFO 是 Last In, First Out 的缩写,中文译为后进先出。这是一种数据结构的工作原则,类似于一摞盘子或一叠书本: 最后放进去的元素最先出来 -想象往筒状容器里放盘子: (1)你放进的最后一个盘子(…...
Python爬虫实战:研究MechanicalSoup库相关技术
一、MechanicalSoup 库概述 1.1 库简介 MechanicalSoup 是一个 Python 库,专为自动化交互网站而设计。它结合了 requests 的 HTTP 请求能力和 BeautifulSoup 的 HTML 解析能力,提供了直观的 API,让我们可以像人类用户一样浏览网页、填写表单和提交请求。 1.2 主要功能特点…...

JavaSec-RCE
简介 RCE(Remote Code Execution),可以分为:命令注入(Command Injection)、代码注入(Code Injection) 代码注入 1.漏洞场景:Groovy代码注入 Groovy是一种基于JVM的动态语言,语法简洁,支持闭包、动态类型和Java互操作性,…...

理解 MCP 工作流:使用 Ollama 和 LangChain 构建本地 MCP 客户端
🌟 什么是 MCP? 模型控制协议 (MCP) 是一种创新的协议,旨在无缝连接 AI 模型与应用程序。 MCP 是一个开源协议,它标准化了我们的 LLM 应用程序连接所需工具和数据源并与之协作的方式。 可以把它想象成你的 AI 模型 和想要使用它…...

华为云Flexus+DeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建
华为云FlexusDeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建 前言 如今大模型其性能出色,华为云 ModelArts Studio_MaaS大模型即服务平台华为云内置了大模型,能助力我们轻松驾驭 DeepSeek-V3/R1,本文中将分享如何…...
管理学院权限管理系统开发总结
文章目录 🎓 管理学院权限管理系统开发总结 - 现代化Web应用实践之路📝 项目概述🏗️ 技术架构设计后端技术栈前端技术栈 💡 核心功能特性1. 用户管理模块2. 权限管理系统3. 统计报表功能4. 用户体验优化 🗄️ 数据库设…...

佰力博科技与您探讨热释电测量的几种方法
热释电的测量主要涉及热释电系数的测定,这是表征热释电材料性能的重要参数。热释电系数的测量方法主要包括静态法、动态法和积分电荷法。其中,积分电荷法最为常用,其原理是通过测量在电容器上积累的热释电电荷,从而确定热释电系数…...

网站指纹识别
网站指纹识别 网站的最基本组成:服务器(操作系统)、中间件(web容器)、脚本语言、数据厍 为什么要了解这些?举个例子:发现了一个文件读取漏洞,我们需要读/etc/passwd,如…...

JVM虚拟机:内存结构、垃圾回收、性能优化
1、JVM虚拟机的简介 Java 虚拟机(Java Virtual Machine 简称:JVM)是运行所有 Java 程序的抽象计算机,是 Java 语言的运行环境,实现了 Java 程序的跨平台特性。JVM 屏蔽了与具体操作系统平台相关的信息,使得 Java 程序只需生成在 JVM 上运行的目标代码(字节码),就可以…...
虚拟电厂发展三大趋势:市场化、技术主导、车网互联
市场化:从政策驱动到多元盈利 政策全面赋能 2025年4月,国家发改委、能源局发布《关于加快推进虚拟电厂发展的指导意见》,首次明确虚拟电厂为“独立市场主体”,提出硬性目标:2027年全国调节能力≥2000万千瓦࿰…...