如何通过Java监听MySQL数据的变化
作者:你好牛蛙 发布时间:2024-01-26 16:05:22
原理
原理:java通过bin-log监控mysql数据变化
binlog :binlog 就是binary log,二进制日志文件,这个文件记录了mysql所有的增、删、改语句。通过binlog日志我们可以做数据恢复,做主从复制等等。可以看到,只要有了这个binlog,我们就拥有了mysql的完整备份了。
就是说一旦开启了这个功能,数据库中数据的任何变化,都会记录到这种日志文件中,所以可以通过Java监听这种的文件,来监听MySQL数据的变化。
开启MySQL的binlog功能
首先,需要开启MySQL的binlog功能,MySQL默认是未开启的
查询是否开始binlog功能的sql语句:show VARIABLES like '%log_bin%';
log_bin的值是on则表示开启,我也不知道没开启是没有这个还是值是off,我也不敢瞎说
开启分为两步,1.改配置 2.重启MySQL服务
改配置
打开自己MySQL的配置文件,比如PC端的即my.ini文件,加上下面三句
log-bin=mysql-bin #[必须]启用二-进制日志
server-id=100 #[必须]服务器唯一ID,如果是用于多台MySQL,ID不要重复就行
binlog-format = ROW #这句也得加,下面解释
改完,然后重启MySQL服务就可以了
说明:
mysql-bin只是个名字而已,可以随便起。将来保存的日志文件名就是mysql-bin.000001,mysql-bin.000002这样的。生成的日志文件会存放在自己的MySQL的存放数据的文件夹,比如我设置的存放MySQL数据的文件夹目录是:D:\MySql\mysql-8.0.24\data\
,然后生成的日志文件就会在这个目录下。
binlog-format = ROW,binlog_format 设置为 ROW可以保证数据的一致, 因为在 STATEMENT 或 MIXED 模式下, Binlog 只会记录和传输 SQL 语句(以减少日志大小),而不包含具体数据,我们也就无法保存了。
Java监听MySQL的binlog实现监听数据变化
Java需要使用一个工具mysql-binlog-connector-java
导入Jar包:
这个Jar包有两个版本,一个是com.github.shyiko的一个是com.zendesk,使用方式和代码完全一样,只是各自的实现方式可能不同,但是com.github.shyiko20年停止更新了,对于MySQL8兼容性不是很好,建议使用com.zendesk。
<dependency>
<groupId>com.zendesk</groupId>
<artifactId>mysql-binlog-connector-java</artifactId>
<version>0.27.1</version> <!--2022.09.17版的-->
</dependency>
顺便附上com.github.shyiko
的
MySQL8及以上使用com.github.shyiko的可能会出现Client does not support authentication protocol requested by server...
错误
原因:mysql8 之前的版本中加密规则是mysql_native_password,而在mysql8之后,加密规则是caching_sha2_password,
解决办法:把mysql用户登录密码加密规则还原成mysql_native_password,
SQL语句:ALTER USER 'root'@'自己需要连接的数据库的host,自己本机的就用localhost' IDENTIFIED WITH mysql_native_password BY '自己所使用的登录密码';
然后就好了
然后再看逻辑代码:
实现是在connectMysqlBinLog()方法中的,里面通过data instanceof ****,即可查询到执行的增删改什么请求,详细请看代码,看一下就明白了
//为什么甚至路径都一样,还是com.github.shyiko.***,
// 因为com.zendesk这个包,里面包了个com.github.shyiko.***这玩意,我怀疑是收购关系
import com.github.shyiko.mysql.binlog.BinaryLogClient;
import com.github.shyiko.mysql.binlog.event.*;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;
import lombok.extern.slf4j.Slf4j;
import java.io.IOException;
//此类可以监控MySQL库数据的增删改
@Component
@Slf4j //用于打印日志
//在SpringBoot中,提供了一个接口:ApplicationRunner。
//该接口中,只有一个run方法,他执行的时机是:spring容器启动完成之后,就会紧接着执行这个接口实现类的run方法。
public class MysqlBinLogClient implements ApplicationRunner {
@Override
public void run(ApplicationArguments args) throws Exception {
//项目启动完成连接bin-log
new Thread(() -> {
connectMysqlBinLog();
}).start();
}
/**
* 连接mysqlBinLog
*/
public void connectMysqlBinLog() {
log.info("监控BinLog服务已启动");
//自己MySQL的信息。host,port,username,password
BinaryLogClient client = new BinaryLogClient("localhost", 3306, "root", "root");
/**因为binlog不是以数据库为单位划分的,所以监控binglog不是监控的单个的数据库,而是整个当前所设置连接的MySQL,
*其中任何一个库发生数据增删改,这里都能检测到,
*所以不用设置所监控的数据库的名字(我也不知道怎么设置,没发现有包含这个形参的构造函数)
*如果需要只监控指定的数据库,可以看后面代码,可以获取到当前发生变更的数据库名称。可以根据名称来决定是否监控
**/
client.setServerId(100); //和自己之前设置的server-id保持一致,但是我不知道为什么不一致也能成功
//下面直接照抄就行
client.registerEventListener(event -> {
EventData data = event.getData();
if (data instanceof TableMapEventData) {
//只要连接的MySQL发生的增删改的操作,则都会进入这里,无论哪个数据库
TableMapEventData tableMapEventData = (TableMapEventData) data;
//可以通过转成TableMapEventData类实例的tableMapEventData来获取当前发生变更的数据库
System.out.println("发生变更的数据库:"+tableMapEventData.getDatabase());
System.out.print("TableID:");
//表ID
System.out.println(tableMapEventData.getTableId());
System.out.print("TableName:");
//表名字
System.out.println(tableMapEventData.getTable());
}
//表数据发生修改时触发
if (data instanceof UpdateRowsEventData) {
System.out.println("Update:");
System.out.println(data.toString());
//表数据发生插入时触发
} else if (data instanceof WriteRowsEventData) {
System.out.println("Insert:");
System.out.println(data.toString());
//表数据发生删除后触发
} else if (data instanceof DeleteRowsEventData) {
System.out.println("Delete:");
System.out.println(data.toString());
}
});
try {
client.connect();
} catch (IOException e) {
e.printStackTrace();
}
}
}
有一定可能数据发生变更后控制台没打印,可能是加载慢的原因,稍等一会控制台就可能会打印相关信息
来源:https://blog.csdn.net/qq_45821251/article/details/127490460


猜你喜欢
- mysql-connector-java与mysql版本的对应我们知道版本更新经常带来的问题就是兼容性问题。在编程过程中版本的错误选择很可能
- 引言JavaScript 的 switch 有四样写法,你知道么?不管你知道不知道,反正我是不知道。我所知道的 JavaScript 的 s
- <html> <head> <script type="text/javascript"&
- 前言在数据分析中,分组聚合二者缺一不可。对数据聚合(求和、平均值等)通常是不可避免的。pd.agg()很方便进行聚合操作。1. 创建Data
- 在SQL SERVER中如何通过SQL语句获取服务器硬件和系统信息呢?下面介绍一下如何通过SQL语句获取处理器(CPU)、内存(Memory
- 银行跨行转账业务是一个典型分布式事务场景,假设 A 需要跨行转账给 B,那么就涉及两个银行的数据,无法通过一个数据库的本地事务保证转账的 A
- pandas创建series方法print("====创建series方法一===")dic={"a"
- 我就废话不多说了,大家还是直接看代码吧!import kerasfrom keras.datasets import cifar10from
- 本文实例为大家分享了微信小程序实现星星评价效果的具体代码,供大家参考,具体内容如下代码实现wxml文件<!--pages/evalua
- 写在前面在写go的时候经常用到序列化、反序列化,记录一下遇到过的坑。空指针会被解析成字符串"null"type Pers
- 前言很多中后台业务的系统中,表格是最高频的组件之一,其中一般包括搜索条件、表格展示、表格操作列、分页等。那么我们二次封装的这个表格组件就需要
- 本文主要是利用Python的第三方库Pillow,实现单通道灰度图像的颜色翻转功能。# -*- encoding:utf-8 -*-impo
- 一、游戏玩法介绍:24点游戏是儿时玩的主要益智类游戏之一,玩法为:从一副扑克中抽取4张牌,对4张牌使用加减乘除中的任何方法,使计算结果为24
- 对于显存不充足的炼丹研究者来说,弄清楚Pytorch显存的分配机制是很有必要的。下面直接通过实验来推出Pytorch显存的分配过程。实验实验
- 本文为大家分享了MySQL 8.0.29 安装配置方法图文教程,供大家参考,具体内容如下一、安装包下载1、下载地址安装包,按下图所示操作下载
- 最近Google Code推出了一个面向网站开发者的 * Google DocType。它来自于网站开发者同时又面
- 1、创建mysite测试站点:django-admin.py startproject mysite 2、创建测试页:hello.py,内容
- 可以实现,下面我们就来做一个检测一个字符串在另一个字符串当中出现几次的函数:入口参数:TheChar="要检测的字符串"
- 思路整理:1、进入心灵鸡汤网页,使用python获取心灵鸡汤内容2、登陆微信,找到需要发送的朋友3、发送获取的内容1、获取心灵鸡汤的内容如下
- python3实现批量修改文件名,供大家参考,具体内容如下以批量修改某文件夹下所有图片名称为例,注释超详细,万能模板,读者可举一反三,适当修