最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

如何通過Java監(jiān)聽MySQL數(shù)據(jù)的變化

 更新時(shí)間:2023年03月14日 11:25:24   作者:你好牛蛙  
對于二次開發(fā)來說,很大一部分就找找文件和找數(shù)據(jù)庫的變化情況,下面這篇文章主要給大家介紹了關(guān)于如何通過Java監(jiān)聽MySQL數(shù)據(jù)的變化的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下

原理

原理:java通過bin-log監(jiān)控mysql數(shù)據(jù)變化

binlog :binlog 就是binary log,二進(jìn)制日志文件,這個(gè)文件記錄了mysql所有的增、刪、改語句。通過binlog日志我們可以做數(shù)據(jù)恢復(fù),做主從復(fù)制等等。可以看到,只要有了這個(gè)binlog,我們就擁有了mysql的完整備份了。

就是說一旦開啟了這個(gè)功能,數(shù)據(jù)庫中數(shù)據(jù)的任何變化,都會(huì)記錄到這種日志文件中,所以可以通過Java監(jiān)聽這種的文件,來監(jiān)聽MySQL數(shù)據(jù)的變化。

開啟MySQL的binlog功能

首先,需要開啟MySQL的binlog功能,MySQL默認(rèn)是未開啟的

查詢是否開始binlog功能的sql語句:show VARIABLES like '%log_bin%';

log_bin的值是on則表示開啟,我也不知道沒開啟是沒有這個(gè)還是值是off,我也不敢瞎說

開啟分為兩步,1.改配置 2.重啟MySQL服務(wù)

改配置

打開自己MySQL的配置文件,比如PC端的即my.ini文件,加上下面三句

log-bin=mysql-bin #[必須]啟用二-進(jìn)制日志
server-id=100 #[必須]服務(wù)器唯一ID,如果是用于多臺(tái)MySQL,ID不要重復(fù)就行
binlog-format = ROW #這句也得加,下面解釋

改完,然后重啟MySQL服務(wù)就可以了

說明:

mysql-bin只是個(gè)名字而已,可以隨便起。將來保存的日志文件名就是mysql-bin.000001,mysql-bin.000002這樣的。生成的日志文件會(huì)存放在自己的MySQL的存放數(shù)據(jù)的文件夾,比如我設(shè)置的存放MySQL數(shù)據(jù)的文件夾目錄是:D:\MySql\mysql-8.0.24\data\,然后生成的日志文件就會(huì)在這個(gè)目錄下。

binlog-format = ROW,binlog_format 設(shè)置為 ROW可以保證數(shù)據(jù)的一致, 因?yàn)樵?STATEMENT 或 MIXED 模式下, Binlog 只會(huì)記錄和傳輸 SQL 語句(以減少日志大小),而不包含具體數(shù)據(jù),我們也就無法保存了。

Java監(jiān)聽MySQL的binlog實(shí)現(xiàn)監(jiān)聽數(shù)據(jù)變化

Java需要使用一個(gè)工具mysql-binlog-connector-java

導(dǎo)入Jar包:

這個(gè)Jar包有兩個(gè)版本,一個(gè)是com.github.shyiko的一個(gè)是com.zendesk,使用方式和代碼完全一樣,只是各自的實(shí)現(xiàn)方式可能不同,但是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的可能會(huì)出現(xiàn)Client does not support authentication protocol requested by server...錯(cuò)誤

原因:mysql8 之前的版本中加密規(guī)則是mysql_native_password,而在mysql8之后,加密規(guī)則是caching_sha2_password,

解決辦法:把mysql用戶登錄密碼加密規(guī)則還原成mysql_native_password,
SQL語句:ALTER USER 'root'@'自己需要連接的數(shù)據(jù)庫的host,自己本機(jī)的就用localhost' IDENTIFIED WITH mysql_native_password BY '自己所使用的登錄密碼';
然后就好了

然后再看邏輯代碼:

實(shí)現(xiàn)是在connectMysqlBinLog()方法中的,里面通過data instanceof ****,即可查詢到執(zhí)行的增刪改什么請求,詳細(xì)請看代碼,看一下就明白了

//為什么甚至路徑都一樣,還是com.github.shyiko.***,
// 因?yàn)閏om.zendesk這個(gè)包,里面包了個(gè)com.github.shyiko.***這玩意,我懷疑是收購關(guān)系
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;

//此類可以監(jiān)控MySQL庫數(shù)據(jù)的增刪改
@Component
@Slf4j  //用于打印日志
//在SpringBoot中,提供了一個(gè)接口:ApplicationRunner。
//該接口中,只有一個(gè)run方法,他執(zhí)行的時(shí)機(jī)是:spring容器啟動(dòng)完成之后,就會(huì)緊接著執(zhí)行這個(gè)接口實(shí)現(xiàn)類的run方法。
public class MysqlBinLogClient implements ApplicationRunner {

    @Override
    public void run(ApplicationArguments args) throws Exception {
        //項(xiàng)目啟動(dòng)完成連接bin-log
        new Thread(() -> {
            connectMysqlBinLog();
        }).start();

    }

    /**
     * 連接mysqlBinLog
     */
    public void connectMysqlBinLog() {
        log.info("監(jiān)控BinLog服務(wù)已啟動(dòng)");

        //自己MySQL的信息。host,port,username,password
        BinaryLogClient client = new BinaryLogClient("localhost", 3306, "root", "root");
        /**因?yàn)閎inlog不是以數(shù)據(jù)庫為單位劃分的,所以監(jiān)控binglog不是監(jiān)控的單個(gè)的數(shù)據(jù)庫,而是整個(gè)當(dāng)前所設(shè)置連接的MySQL,
         *其中任何一個(gè)庫發(fā)生數(shù)據(jù)增刪改,這里都能檢測到,
         *所以不用設(shè)置所監(jiān)控的數(shù)據(jù)庫的名字(我也不知道怎么設(shè)置,沒發(fā)現(xiàn)有包含這個(gè)形參的構(gòu)造函數(shù))
         *如果需要只監(jiān)控指定的數(shù)據(jù)庫,可以看后面代碼,可以獲取到當(dāng)前發(fā)生變更的數(shù)據(jù)庫名稱??梢愿鶕?jù)名稱來決定是否監(jiān)控
         **/

        client.setServerId(100); //和自己之前設(shè)置的server-id保持一致,但是我不知道為什么不一致也能成功

//下面直接照抄就行
        client.registerEventListener(event -> {
            EventData data = event.getData();
            if (data instanceof TableMapEventData) {
                //只要連接的MySQL發(fā)生的增刪改的操作,則都會(huì)進(jìn)入這里,無論哪個(gè)數(shù)據(jù)庫

                TableMapEventData tableMapEventData = (TableMapEventData) data;

                //可以通過轉(zhuǎn)成TableMapEventData類實(shí)例的tableMapEventData來獲取當(dāng)前發(fā)生變更的數(shù)據(jù)庫
                System.out.println("發(fā)生變更的數(shù)據(jù)庫:"+tableMapEventData.getDatabase());

                System.out.print("TableID:");
                //表ID
                System.out.println(tableMapEventData.getTableId());
                System.out.print("TableName:");
                //表名字
                System.out.println(tableMapEventData.getTable());
            }
            //表數(shù)據(jù)發(fā)生修改時(shí)觸發(fā)
            if (data instanceof UpdateRowsEventData) {
                System.out.println("Update:");
                System.out.println(data.toString());
                //表數(shù)據(jù)發(fā)生插入時(shí)觸發(fā)
            } else if (data instanceof WriteRowsEventData) {
                System.out.println("Insert:");
                System.out.println(data.toString());
                //表數(shù)據(jù)發(fā)生刪除后觸發(fā)
            } else if (data instanceof DeleteRowsEventData) {
                System.out.println("Delete:");
                System.out.println(data.toString());
            }
        });

        try {
            client.connect();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}

有一定可能數(shù)據(jù)發(fā)生變更后控制臺(tái)沒打印,可能是加載慢的原因,稍等一會(huì)控制臺(tái)就可能會(huì)打印相關(guān)信息

總結(jié)

到此這篇關(guān)于如何通過Java監(jiān)聽MySQL數(shù)據(jù)的變化的文章就介紹到這了,更多相關(guān)Java監(jiān)聽MySQL數(shù)據(jù)變化內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java?API操作Hdfs的示例詳解

    Java?API操作Hdfs的示例詳解

    這篇文章主要介紹了Java?API操作Hdfs詳細(xì)示例,遍歷當(dāng)前目錄下所有文件與文件夾,可以使用listStatus方法實(shí)現(xiàn)上述需求,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2022-08-08
  • Spring Boot Log4j2的配置使用詳解

    Spring Boot Log4j2的配置使用詳解

    本篇文章主要介紹了Spring Boot Log4j2的配置使用詳解,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-05-05
  • java 泛型的詳解及實(shí)例

    java 泛型的詳解及實(shí)例

    這篇文章主要介紹了java 泛型的詳解及實(shí)例的相關(guān)資料,希望通過本文大家能徹底掌握泛型的使用方法,需要的朋友可以參考下
    2017-08-08
  • mybatis映射文件操作存儲(chǔ)過程的實(shí)現(xiàn)

    mybatis映射文件操作存儲(chǔ)過程的實(shí)現(xiàn)

    本文主要介紹了mybatis映射文件操作存儲(chǔ)過程的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-03-03
  • Java中的set集合是什么意思

    Java中的set集合是什么意思

    這篇文章主要介紹了Java中的set集合是什么意思,詳細(xì)地講解一下Collection集合中的另外一個(gè)分支——Set系列集合,需要的朋友可以參考下
    2022-05-05
  • 詳解spring中aop不生效的幾種解決辦法

    詳解spring中aop不生效的幾種解決辦法

    這篇文章主要介紹了詳解spring中aop不生效的幾種解決辦法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-06-06
  • SpringBoot實(shí)現(xiàn)統(tǒng)一封裝返回前端結(jié)果集的示例代碼

    SpringBoot實(shí)現(xiàn)統(tǒng)一封裝返回前端結(jié)果集的示例代碼

    在實(shí)際項(xiàng)目開發(fā)過程中,我們經(jīng)常將返回?cái)?shù)據(jù)的基本形式統(tǒng)一為JSON格式的數(shù)據(jù)。但項(xiàng)目可能是由很多人開發(fā)的,所以我們最好將返回的結(jié)果統(tǒng)一起來。本文介紹了SpringBoot實(shí)現(xiàn)統(tǒng)一封裝返回前端結(jié)果集的示例代碼,需要的可以參考一下
    2022-06-06
  • 解析Java中的static關(guān)鍵字

    解析Java中的static關(guān)鍵字

    static是方便在沒有創(chuàng)建對象的情況下進(jìn)行調(diào)用(方法/變量)。顯然,被static關(guān)鍵字修飾的方法或者變量不需要依賴于對象來進(jìn)行訪問,只要類被加載了,就可以通過類名去進(jìn)行訪問。static可以用來修飾類的成員方法、類的成員變量,另外也可以編寫static代碼塊來優(yōu)化程序性能
    2021-06-06
  • 解決Nacos成功啟動(dòng)但是無法訪問 (Connection refused)

    解決Nacos成功啟動(dòng)但是無法訪問 (Connection refused)

    這篇文章主要介紹了解決Nacos成功啟動(dòng)但是無法訪問 (Connection refused)問題,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-06-06
  • redisson 實(shí)現(xiàn)分布式鎖的源碼解析

    redisson 實(shí)現(xiàn)分布式鎖的源碼解析

    這篇文章主要介紹了redisson 實(shí)現(xiàn)分布式鎖的源碼解析,通過模擬一個(gè)商品秒殺的場景結(jié)合示例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-05-05

最新評論

湖北省| 墨脱县| 外汇| 莱阳市| 陵水| 曲水县| 左权县| 宿迁市| 蓬莱市| 三河市| 阿拉善左旗| 获嘉县| 文成县| 鄂托克旗| 南丹县| 连平县| 闸北区| 横山县| 西宁市| 香港 | 杨浦区| 富阳市| 金溪县| 涡阳县| 鄂温| 蒙自县| 新安县| 枣庄市| 金平| 临沭县| 永和县| 西平县| 丹凤县| 陵川县| 炉霍县| 正蓝旗| 马龙县| 蒙城县| 韶关市| 尖扎县| 长泰县|