通过Java监听MySQL数据的变化
实现Java监听MySQL数据是否发生变化
原理
原理: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.zendeskgroupId> <artifactId>mysql-binlog-connector-javaartifactId> <version>0.27.1version> 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(); } public void connectMysqlBinLog() { log.info("监控BinLog服务已启动"); //自己MySQL的信息。host,port,username,password BinaryLogClient client = new BinaryLogClient("localhost", 3306, "root", "root"); 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
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341