服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - Java教程 - 如何通过Java监听MySQL数据的变化

如何通过Java监听MySQL数据的变化

2023-03-16 14:29你好牛蛙 Java教程

对于二次开发来说,很大一部分就找找文件和找数据库的变化情况,下面这篇文章主要给大家介绍了关于如何通过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文件,加上下面三句

?
1
2
3
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。

?
1
2
3
4
5
<dependency>
    <groupId>com.zendesk</groupId>
    <artifactId>mysql-binlog-connector-java</artifactId>
    <version>0.27.1</version> <!--2022.09.17版的-->
</dependency>

顺便附上com.github.shyiko

如何通过Java监听MySQL数据的变化

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 ****,即可查询到执行的增删改什么请求,详细请看代码,看一下就明白了

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
//为什么甚至路径都一样,还是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();
        }
 
    }
}

有一定可能数据发生变更后控制台没打印,可能是加载慢的原因,稍等一会控制台就可能会打印相关信息

总结

到此这篇关于如何通过Java监听MySQL数据的变化的文章就介绍到这了,更多相关Java监听MySQL数据变化内容请搜索服务器之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持服务器之家!

原文链接:https://blog.csdn.net/qq_45821251/article/details/127490460

延伸 · 阅读

精彩推荐
  • Java教程java异常机制分析

    java异常机制分析

    这篇文章主要介绍了java异常机制,包括异常机制的捕获、抛出及常见的异常机制总结,需要的朋友可以参考下 ...

    shichen20142472019-11-28
  • Java教程剑指Offer之Java算法习题精讲求和篇

    剑指Offer之Java算法习题精讲求和篇

    跟着思路走,之后从简单题入手,反复去看,做过之后可能会忘记,之后再做一次,记不住就反复做,反复寻求思路和规律,慢慢积累就会发现质的变化...

    明天一定.9082022-10-09
  • Java教程Java互斥锁简单实例

    Java互斥锁简单实例

    这篇文章主要介绍了Java互斥锁,较为详细的分析了java互斥锁的概念与功能,并实例描述了java互斥锁的原理与使用技巧,具有一定参考借鉴价值,需要的朋友可以...

    优雅先生2872019-12-26
  • Java教程小项目改造快速引入 mybatis的流程分析

    小项目改造快速引入 mybatis的流程分析

    这篇文章主要介绍了小项目改造快速引入 mybatis,功能方面非常简单,考虑到开发速度,直接按 springboot 项目进行开发,依赖方面仅仅使用 spring-boot-starter-...

    安逸的咸鱼8032023-01-28
  • Java教程2022最新Java JDK1.8的安装超详细教程

    2022最新Java JDK1.8的安装超详细教程

    jdk1.8又称jdk8.0,是目前相对比较稳定的版本,不建议下载最新的jdk版本,因为最新版的jdk不稳定,在Java的学习中可能会出现各种各样的问题,今天通过本文...

    思无邪i9152022-11-01
  • Java教程Java中生成随机数Random VS ThreadLocalRandom性能比较

    Java中生成随机数Random VS ThreadLocalRandom性能比较

    大家项目中如果有生成随机数的需求,我想大多都会选择使用Random来实现,它内部使用了CAS来实现。实际上,JDK1.7之后,提供了另外一个生成随机数的类...

    JAVA旭阳9012022-12-15
  • Java教程java动态导出excel压缩成zip下载的方法

    java动态导出excel压缩成zip下载的方法

    这篇文章主要为大家详细介绍了java动态导出excel压缩成zip下载的方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    张虹旺9512021-05-17
  • Java教程优化MyBatis配置文件中的配置详解

    优化MyBatis配置文件中的配置详解

    这篇文章主要介绍了优化MyBatis配置文件中的配置详解,分享了相关代码示例,小编觉得还是挺不错的,具有一定借鉴价值,需要的朋友可以参考下...

    小江_xiaojiang3982021-03-31