iis服务器助手广告广告
返回顶部
首页 > 资讯 > 精选 >Springboot2.3.x整合Canal的方法
  • 742
分享到

Springboot2.3.x整合Canal的方法

2023-06-29 05:06:05 742人浏览 泡泡鱼
摘要

这篇文章主要介绍“SpringBoot2.3.x整合Canal的方法”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“springboot2.3.x整合Canal的方法”文章能帮助大家解决问题。一、故事

这篇文章主要介绍“SpringBoot2.3.x整合Canal的方法”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“springboot2.3.x整合Canal的方法”文章能帮助大家解决问题。

    一、故事背景

    最近工作中遇到了一个数据同步的问题

    我们这边系统的一个子业务需要依赖另一个系统的数据,当另一个系统数据变更时,我们这边的数据库要对数据进行同步…

    那么我自己想到的同步方式呢就两种:

    MQ订阅,另一个系统数据变更后将变更数据方式到MQ 我们这边订阅接受

    数据库的触发器

    但是呢,两者都被组长paas了!

    MQ呢,会造成代码侵入,但是另一个系统暂时不会做任何代码更改…

    数据库的触发器会直接跟生产数据库强关联,会抢占资源,甚至有可能造成生产数据库的不稳定…

    对此很是苦恼…

    于是啊,只能借由强大的Google、百度,看看能不能解决我这个问题!一番搜索,有学习了一个很有趣的东西

    二、什么是Canal

    canal:阿里开源mysql binlog 数据组件

    早期,阿里巴巴B2B公司因为存在杭州和美国双机房部署,存在跨机房同步的业务需求。不过早期的数据库同步业务,主要是基于trigger的方式获取增量变更,不过从2010年开始,阿里系公司开始逐步的尝试基于数据库的日志解析,获取增量变更进行同步,由此衍生出了增量订阅&消费的业务,从此开启了一段新纪元。ps. 目前内部使用的同步,已经支持Mysql5.x和oracle部分版本的日志解析

    Springboot2.3.x整合Canal的方法

    canal [kə’næl],译意为水道/管道/沟渠,主要用途是基于 mysql 数据库增量日志解析,提供增量数据订阅和消费

    工作原理

    • canal 模拟 Mysql slave 的交互协议,伪装自己为 MySQL slave ,向 MySQL master 发送 dump 协议

    • MySQL master 收到 dump 请求,开始推送 binary log 给 slave (即 canal )

    • canal 解析 binary log 对象(原始为 byte 流)

    canal呢,实际是就是运用了Mysql的主从复制原理…

    MySQL主从复制实现

    Springboot2.3.x整合Canal的方法

    复制遵循三步过程:

    • 服务器将更改记录到binlog中(这些记录称为binlog事件,可以通过来查看show binary events

    • 服务器将主服务器的二进制日志事件复制到其中继日志。

    • 中继日志中的从服务器重做事件随后将更新其旧数据。

    如何运作

    Springboot2.3.x整合Canal的方法

    原理很简单:

    • Canal模拟MySQL从站的交互协议,伪装成MySQL从站,然后将转储协议发送到MySQL主服务器。

    • MySQL Master接收到转储请求,并开始将二进制日志推送到slave(即运河)。

    • 运河将二进制日志对象解析为其自己的数据类型(最初为字节流)

    通过官网的介绍,让我们了解到,canal实际上就是伪装为了一个从库,我们只需要订阅到数据变更的主库,那么canal就会以从库的身份读取到其主库的binlog日志!我们拿到canal解析好的binlog日志信息,就等于拿到了变更的数据啦!

    三、Canal安装

    (1)事前准备

    (1)数据库开启binlog

    使用canal呢,有一个前提条件,即被订阅的数据库需要开启binlog

    如何查看是否开启binlog呢?

    登录服务器上数据库或在可视化工具中 执行查询语句: 如果出现 log_bin ON 表示已开启Binlog

    show variables like 'log_bin';

    Springboot2.3.x整合Canal的方法

    如果服务器上的数据库为自己安装的,则找到配置文件my.conf 添加以下内容,如果买的云实例,则询问厂商开启即可

    Springboot2.3.x整合Canal的方法

    在my.conf文件中的 [mysqld] 下添加以下三行内容

    log-bin=mysql-bin # 开启 binlogbinlog-fORMat=ROW # 选择 ROW 模式 读行server_id=1 # 配置 MySQL replaction 需要定义,不要和 canal 的 slaveId 重复
    (2)数据库新建账号,开启MySQL slav权限

    canaltest:作为slave 角色的账户 Canal123…:为密码

    CREATE USER canaltest IDENTIFIED BY 'Canal123..';  GRANT SELECT, REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'canaltest'@'%';GRANT ALL PRIVILEGES ON *.* TO 'canaltest'@'%' ;FLUSH PRIVILEGES;

    Springboot2.3.x整合Canal的方法

    连接测试

    Springboot2.3.x整合Canal的方法

    那么到这里,准备工作就好了!

    可能呢,有的小伙伴有点懵,你这是在干啥?那么咱们就来理那么一理! 敲黑板了哈!

    Springboot2.3.x整合Canal的方法

    1、事前准备,是针对于订阅数据库的(即主库)

    2、实际步骤也就两步 1:更改配置,开启binlog 2:设置新账号,赋予slave权限,供canal读取Binlog桥梁使用

    3、以上操作与canal本身没啥关系,仅仅是使用canal的前提条件罢辽…

    (2)Canal Admin 安装

    canal admin 是 一个可视化的 canal WEB管理运维工程,脱离以往服务器运维,面向web…

    canal-admin设计上是为canal提供整体配置管理、节点运维等面向运维的功能,提供相对友好的WebUI操作界面,方便更多用户快速和安全的操作

    canal-admin的限定依赖:

    • MySQL,用于存储配置和节点等相关数据

    • canal版本,要求>=1.1.4 (需要依赖canal-server提供面向admin的动态运维管理接口)

    • 需要JRE 环境 (安装jdk)

    下载

    wget https://GitHub.com/alibaba/canal/releases/download/canal-1.1.4/canal.admin-1.1.4.tar.gz

    解压

    mkdir /usr/local/canal-admintar zxvf canal.admin-1.1.4.tar.gz  -C /usr/local/canal-admin

    进入canal-admin目录下查看

    cd /usr/local/canal-admin

    修改配置

    vim conf/application.yml

    里边的配置 按照自己的实际情况更改…

    server:  port: 8089spring:  jackson:    date-format: yyyy-MM-dd HH:mm:ss    time-zone: GMT+8#这里是配置canal-admin 所依赖的数据库,,,存放web管理中设置的配置等,,,spring.datasource:  address: 127.0.0.1:3306  database: canal_manager  username: root  passWord: 123456  driver-class-name: com.mysql.jdbc.Driver  url: jdbc:mysql://${spring.datasource.address}/${spring.datasource.database}?useUnicode=true&characterEncoding=UTF-8&useSSL=false  hikari:    maximum-pool-size: 30    minimum-idle: 1# 连接所用的账户密码 canal:  adminUser: admin  adminPasswd: leitest

    导入canaladmin 所需要的数据库文件

    这里需要注意了,要和 application.yml中的数据库名对应,你可以选择命令导入,也可以Navicat 可视化拖sql文件导入…一切…看你喜欢.

    我这个玩canal的服务器呢,是新安装的,mysql直接用Docker安装即可,具体可查看我的博客:

    Docker在Centos7下不能下载镜像timeout的解决办法(图解)

    CentOS 7安装Docker

    需要注意的是,使用docker 安装的mysql 是无法直接使用 mysql -uroot -p 命令的哦,需要先将脚本复制到容器中,docker不熟练或觉得麻烦的同鞋,请直接使用Navicat可视化工具…

    导入canal-admin服务所必需的sql文件

    如果是服务器软件软件安装的mysql 则直接执行以下命令即可

    mysql -uroot -p#.........# 导入初始化SQL> source conf/canal_manager.sql

    Springboot2.3.x整合Canal的方法

    启动

    直接执行启动脚本即可

    cd bin./startup.sh

    Springboot2.3.x整合Canal的方法

    默认账户密码:

    admin:123456

    Springboot2.3.x整合Canal的方法

    (3)Canal Server 安装

    canal-server 才是canal的核心我们前边所讲的canal的功能,实际上讲述的就是canal-server的功能…admin 仅仅只是一个web管理而已,不要搞混主次关系…

    下载

    wget Https://github.com/alibaba/canal/releases/download/canal-1.1.4/canal.deployer-1.1.4.tar.gz

    解压

    mkdir /usr/local/canal-servertar zxvf canal.deployer-1.1.4.tar.gz  -C /usr/local/canal-server

    启动,并连接到canal-admin web端

    首先,我们需要修改配置文件

    cd /usr/local/canal-servervim /conf/canal_local.properties

    Springboot2.3.x整合Canal的方法

    Springboot2.3.x整合Canal的方法

    注意了,密码如何加密!!!

    要记得,前边 canal-admin 的 aplication.yml 中设置了账户密码为 admin:leitest

    # 连接所用的账户密码 canal:  adminUser: admin  adminPasswd: leitest

    所以,我们这里需要对明文 leitest 加密并替换即可

    使用数据库函数 PASSWORD 加密即可

    SELECT PASSWORD(‘要加密的明文’),然后去掉前边的* 号就行

    Springboot2.3.x整合Canal的方法

    启动并连接到admin

    sh bin/startup.sh local

    查看端口看是否有 11110 、11111、11112

    netstat -untlp 看了一下,发现没有,说明server 没有启动成功

    Springboot2.3.x整合Canal的方法

    看下日志

    vim logs/canal/canal.log

    Springboot2.3.x整合Canal的方法

    解决办法:

    canal-admin 先停止后从起

    canal server 先以之前的形式运行,不输入后边 local 命令

    关闭canal server

    再以canal server 连接 admin 形式启动

    Springboot2.3.x整合Canal的方法

    admin页面上新建server

    Springboot2.3.x整合Canal的方法

    修改配置,注释 (instance连接信息,我们还是以前边设置的 admin:leitest 为准,所有这里需要注释掉,如果不注释,那么我们代码中连接则需要使用此账号以及密码)

    Springboot2.3.x整合Canal的方法

    接下来咱们创建instance

    如何理解server 和instance 呢,我认为,可以把它当做 java 中的 class 和 bean 即 类和对象

    server 为类 instance 为其具体的实例对象 ,可创建多个不同的实例…

    而我们这边监听到主库变化的呢,则是根据业务,对不同的实例即(instance )做不同配置即可…

    Springboot2.3.x整合Canal的方法

    Springboot2.3.x整合Canal的方法

    Springboot2.3.x整合Canal的方法

    Springboot2.3.x整合Canal的方法

    根据自己情况进行过滤数据

    canal.instance.filter.regexmysql 数据解析关注的表,Perl正则表达式.多个正则之间以逗号(,)分隔,转义符需要双斜杠(\) 常见例子:1. 所有表:.* or .\… 2. canal schema下所有表: canal\…* 3. canal下的以canal打头的表:canal\.canal.* 4. canal schema下的一张表:canal\.test15. 多个规则组合使用:canal\…*,mysql.test1,mysql.test2 (逗号分隔)  
    canal.instance.filter.druid.ddl是否使用druid处理所有的ddl解析来获取库和表名true 
    canal.instance.filter.query.dcl是否忽略dcl语句false 
    canal.instance.filter.query.dml是否忽略dml语句 (mysql5.6之后,在row模式下每条DML语句也会记录SQL到binlog中,可参考MySQL文档)false 
    canal.instance.filter.query.ddl是否忽略ddl语句false 

    更多设置请见官网:https://github.com/alibaba/canal/wiki/AdminGuide

    如此一来,一个简单的canal环境就搭建好了,接下来,咱们开始测试吧!

    (4)springboot demo示例

    引入canal所需依赖

    <dependency>            <groupId>com.alibaba.otter</groupId>            <artifactId>canal.client</artifactId>            <version>1.1.4</version>        </dependency>

    配置

    canal:  # instance 实例所在ip  host: 192.168.96.129  # tcp通信端口  port: 11111  # 账号  canal-admin application.yml 设置的  username: admin  # 密码  password: leitest  #实例名称  instance: test

    代码

    package com.leilei;import com.alibaba.otter.canal.client.CanalConnector;import com.alibaba.otter.canal.client.CanalConnectors;import com.alibaba.otter.canal.protocol.CanalEntry;import com.alibaba.otter.canal.protocol.Message;import org.springframework.beans.factory.annotation.Value;import org.springframework.boot.ApplicationArguments;import org.springframework.boot.ApplicationRunner;import org.springframework.stereotype.Component;import java.net.InetSocketAddress;import java.util.List;@Componentpublic class ReadBinLogService implements ApplicationRunner {    @Value("${canal.host}")    private String host;    @Value("${canal.port}")    private int port;    @Value("${canal.username}")    private String username;    @Value("${canal.password}")    private String password;    @Value("${canal.instance}")    private String instance;    @Override    public void run(ApplicationArguments args) throws Exception {        CanalConnector conn = getConn();        while (true) {            conn.connect();            //订阅实例中所有的数据库和表            conn.subscribe(".*\\..*");            // 回滚到未进行ack的地方            conn.rollback();            // 获取数据 每次获取一百条改变数据            Message message = conn.getWithoutAck(100);            long id = message.getId();            int size = message.getEntries().size();            if (id != -1 && size > 0) {                // 数据解析                analysis(message.getEntries());            }else {                Thread.sleep(1000);            }            // 确认消息            conn.ack(message.getId());            // 关闭连接            conn.disconnect();        }    }        private void analysis(List<CanalEntry.Entry> entries) {        for (CanalEntry.Entry entry : entries) {            // 只解析mysql事务的操作,其他的不解析            if (entry.getEntryType() == CanalEntry.EntryType.TRANSACTIONBEGIN) {                continue;            if (entry.getEntryType() == CanalEntry.EntryType.TRANSACTIONEND) {            // 解析binlog            CanalEntry.RowChange rowChange = null;            try {                rowChange = CanalEntry.RowChange.parseFrom(entry.getStoreValue());            } catch (Exception e) {                throw new RuntimeException("解析出现异常 data:" + entry.toString(), e);            if (rowChange != null) {                // 获取操作类型                CanalEntry.EventType eventType = rowChange.getEventType();                // 获取当前操作所属的数据库                String dbName = entry.getHeader().getSchemaName();                // 获取当前操作所属的表                String tableName = entry.getHeader().getTableName();                // 事务提交时间                long timestamp = entry.getHeader().getExecuteTime();                for (CanalEntry.RowData rowData : rowChange.getRowDatasList()) {                    dataDetails(rowData.getBeforeColumnsList(), rowData.getAfterColumnsList(), dbName, tableName, eventType, timestamp);                    System.out.println("-------------------------------------------------------------");                }     * 解析具体一条Binlog消息的数据     *     * @param dbName    当前操作所属数据库名称     * @param tableName 当前操作所属表名称     * @param eventType 当前操作类型(新增、修改、删除)    private static void dataDetails(List<CanalEntry.Column> beforeColumns,                                    List<CanalEntry.Column> afterColumns,                                    String dbName,                                    String tableName,                                    CanalEntry.EventType eventType,                                    long timestamp) {        System.out.println("数据库:" + dbName);        System.out.println("表名:" + tableName);        System.out.println("操作类型:" + eventType);        if (CanalEntry.EventType.INSERT.equals(eventType)) {            System.out.println("新增数据:");            printColumn(afterColumns);        } else if (CanalEntry.EventType.DELETE.equals(eventType)) {            System.out.println("删除数据:");            printColumn(beforeColumns);        } else {            System.out.println("更新数据:更新前数据--");            System.out.println("更新数据:更新后数据--");        System.out.println("操作时间:" + timestamp);    private static void printColumn(List<CanalEntry.Column> columns) {        for (CanalEntry.Column column : columns) {            System.out.println(column.getName() + " : " + column.getValue() + "    update=" + column.getUpdated());     * 获取连接    public CanalConnector getConn() {        return CanalConnectors.newSingleConnector(new InetSocketAddress(host, port), instance, username, password);}

    测试查看

    数据库修改数据库时

    Springboot2.3.x整合Canal的方法

    数据新增数据时

    Springboot2.3.x整合Canal的方法

    删除数据(把我们才添加的小明删掉)

    Springboot2.3.x整合Canal的方法

    当我们操作监控的数据库DM L操作的时候呢,会被canal监听到&hellip;我们呢,通过canal监听,拿到修改的库,修改的表,修改的字段,便可以根据自己业务进行数据处理了!

    哎,这个时候啊,可能有小伙伴就要问了,那么,我能不能直接获取其操作的sql语句呢?

    目前,我是自己解析其列来手动拼接的sql语句实现了

    话不多说,先上效果:

    canal 监听到主库sql变化----> update students set  id = '2', age = '999', name = '小三', city = '11', date = '2020-09-27 17:41:44', birth = '2020-09-27 18:00:48' where id=2
    canal 监听到主库sql变化----> delete from students where id=6
    canal 监听到主库sql变化----> insert into students (id,age,name,city,date,birth) VALUES ('89','98','测试新增','深圳','2020-09-27 22:46:53','')
    canal 监听到主库sql变化----> update students set  id = '89', age = '98', name = '测试新增', city = '深圳', date = '2020-09-27 22:46:53', birth = '2020-09-27 22:46:56' where id=89

    Springboot2.3.x整合Canal的方法

    实际上呢,我们也就是拿到其执行前列数据变化 执行后列数据变化,自己拼接了一个sql罢了&hellip;附上代码

    package com.leilei;import com.alibaba.otter.canal.client.CanalConnector;import com.alibaba.otter.canal.client.CanalConnectors;import com.alibaba.otter.canal.protocol.CanalEntry.*;import com.alibaba.otter.canal.protocol.Message;import com.alibaba.otter.canal.protocol.exception.CanalClientException;import com.google.protobuf.InvalidProtocolBufferException;import org.springframework.beans.factory.annotation.Value;import org.springframework.boot.ApplicationArguments;import org.springframework.boot.ApplicationRunner;import org.springframework.stereotype.Component;import java.net.InetSocketAddress;import java.util.List;import java.util.Queue;import java.util.concurrent.ConcurrentLinkedQueue;@Componentpublic class ReadBinLogToSql implements ApplicationRunner {    //读取的binlog sql 队列缓存 一边Push 一边poll    private Queue<String> canalQueue = new ConcurrentLinkedQueue<>();    @Value("${canal.host}")    private String host;    @Value("${canal.port}")    private int port;    @Value("${canal.username}")    private String username;    @Value("${canal.password}")    private String password;    @Value("${canal.instance}")    private String instance;    @Override    public void run(ApplicationArguments args) throws Exception {        CanalConnector conn = getConn();        while (true) {            try {                conn.connect();                //订阅实例中所有的数据库和表                conn.subscribe(".*\\..*");                // 回滚到未进行ack的地方                conn.rollback();                // 获取数据 每次获取一百条改变数据                Message message = conn.getWithoutAck(100);                long id = message.getId();                int size = message.getEntries().size();                if (id != -1 && size > 0) {                    // 数据解析                    analysis(message.getEntries());                } else {                    Thread.sleep(1000);                }                // 确认消息                conn.ack(message.getId());            } catch (CanalClientException | InvalidProtocolBufferException | InterruptedException e) {                e.printStackTrace();            } finally {                // 关闭连接                conn.disconnect();            }        }    }    private void analysis(List<Entry> entries) throws InvalidProtocolBufferException {        for (Entry entry : entries) {            if (EntryType.ROWDATA == entry.getEntryType()) {                RowChange rowChange = RowChange.parseFrom(entry.getStoreValue());                EventType eventType = rowChange.getEventType();                if (eventType == EventType.DELETE) {                    saveDeleteSql(entry);                } else if (eventType == EventType.UPDATE) {                    saveUpdateSql(entry);                } else if (eventType == EventType.INSERT) {                    saveInsertSql(entry);                }            }        }    }        private void saveUpdateSql(Entry entry) {        try {            RowChange rowChange = RowChange.parseFrom(entry.getStoreValue());            List<RowData> dataList = rowChange.getRowDatasList();            for (RowData rowData : dataList) {                List<Column> afterColumnsList = rowData.getAfterColumnsList();                StringBuffer sql = new StringBuffer("update " +                        entry.getHeader().getTableName() + " set ");                for (int i = 0; i < afterColumnsList.size(); i++) {                    sql.append(" ")                            .append(afterColumnsList.get(i).getName())                            .append(" = '").append(afterColumnsList.get(i).getValue())                            .append("'");                    if (i != afterColumnsList.size() - 1) {                        sql.append(",");                    }                }                sql.append(" where ");                List<Column> oldColumnList = rowData.getBeforeColumnsList();                for (Column column : oldColumnList) {                    if (column.getIsKey()) {                        sql.append(column.getName()).append("=").append(column.getValue());                        break;                    }                }                canalQueue.add(sql.toString());            }        } catch (InvalidProtocolBufferException e) {            e.printStackTrace();        }    }        private void saveDeleteSql(Entry entry) {        try {            RowChange rowChange = RowChange.parseFrom(entry.getStoreValue());            List<RowData> rowDatasList = rowChange.getRowDatasList();            for (RowData rowData : rowDatasList) {                List<Column> columnList = rowData.getBeforeColumnsList();                StringBuffer sql = new StringBuffer("delete from " +                        entry.getHeader().getTableName() + " where ");                for (Column column : columnList) {                    if (column.getIsKey()) {                        sql.append(column.getName()).append("=").append(column.getValue());                        break;                    }                }                canalQueue.add(sql.toString());            }        } catch (InvalidProtocolBufferException e) {            e.printStackTrace();        }    }        private void saveInsertSql(Entry entry) {        try {            RowChange rowChange = RowChange.parseFrom(entry.getStoreValue());            List<RowData> datasList = rowChange.getRowDatasList();            for (RowData rowData : datasList) {                List<Column> columnList = rowData.getAfterColumnsList();                StringBuffer sql = new StringBuffer("insert into " +                        entry.getHeader().getTableName() + " (");                for (int i = 0; i < columnList.size(); i++) {                    sql.append(columnList.get(i).getName());                    if (i != columnList.size() - 1) {                        sql.append(",");                    }                }                sql.append(") VALUES (");                for (int i = 0; i < columnList.size(); i++) {                    sql.append("'" + columnList.get(i).getValue() + "'");                    if (i != columnList.size() - 1) {                        sql.append(",");                    }                }                sql.append(")");                canalQueue.add(sql.toString());            }        } catch (InvalidProtocolBufferException e) {            e.printStackTrace();        }    }        public CanalConnector getConn() {        return CanalConnectors.newSingleConnector(new InetSocketAddress(host, port), instance, username, password);    }        public void executeQueueSql() {        int size = canalQueue.size();        for (int i = 0; i < size; i++) {            String sql = canalQueue.poll();            System.out.println("canal 监听到主库sql变化----> " + sql);        }    }}

    关于“Springboot2.3.x整合Canal的方法”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识,可以关注编程网精选频道,小编每天都会为大家更新不同的知识点。

    --结束END--

    本文标题: Springboot2.3.x整合Canal的方法

    本文链接: https://www.lsjlt.com/news/322978.html(转载时请注明来源链接)

    有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

    本篇文章演示代码以及资料文档资料下载

    下载Word文档到电脑,方便收藏和打印~

    下载Word文档
    猜你喜欢
    • Springboot2.3.x整合Canal的方法
      这篇文章主要介绍“Springboot2.3.x整合Canal的方法”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Springboot2.3.x整合Canal的方法”文章能帮助大家解决问题。一、故事...
      99+
      2023-06-29
    • Springboot2.3.x整合Canal的示例代码
      目录一、故事背景二、什么是Canal三、Canal安装(1)事前准备(1)数据库开启binlog(2)数据库新建账号,开启MySQL slav权限(2)Canal Admin 安装(...
      99+
      2024-04-02
    • SpringBoot整合Canal方法详解
      目录pom.xml 添加 canal.client 依赖业务功能处理简单连接程序单次获取数据循环获取数据解析 storeValue 值不同的类型进行不同的处理一次性获取多条数据ack...
      99+
      2022-12-21
      SpringBoot整合Canal SpringBoot Canal
    • SpringBoot怎么整合Canal方法
      这篇“SpringBoot怎么整合Canal方法”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“SpringBoot怎么整合C...
      99+
      2023-07-04
    • SpringBoot整合Canal数据同步的方法
      这篇文章主要介绍“SpringBoot整合Canal数据同步的方法”,在日常操作中,相信很多人在SpringBoot整合Canal数据同步的方法问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”SpringBoo...
      99+
      2023-06-29
    • springboot2.x只需两步快速整合log4j2的方法
      前言 本文详细介绍如何使用spring-boot2.x快速整合log4j2日志框架。 spring-boot2.x使用logback作为默认日志处理库,因此我们除了要引用log4j...
      99+
      2024-04-02
    • 关于SpringBoot整合Canal数据同步的问题
      目录1、CentOS7编译安装MySQL5.7.242、Mysql设置binLog配置3、Linux下载安装Canal服务4、Boot项目中引入依赖5 、修改properties配置...
      99+
      2024-04-02
    • SpringBoot整合canal实现数据同步的示例代码
      目录一、前言二、docker-compose部署canal三、canal-admin可视化管理四、springboot整合canal实现数据同步五、canal-spring-boot...
      99+
      2024-04-02
    • SpringBoot整合Thymeleaf的方法
      目录1. 问题需求分析2. 什么是静态化?3. 如何实现静态化?4. Thymeleaf实现静态化4.1 概念介绍三个参数:4.2 具体实现5. nginx 中进行访问配置6. 访问...
      99+
      2024-04-02
    • Spark整合Mongodb的方法
      Spark介绍 按照官方的定义,Spark 是一个通用,快速,适用于大规模数据的处理引擎。 通用性:我们可以使用Spark SQL来执行常规分析, Spark Streaming 来流数据处理, 以及用Ml...
      99+
      2024-04-02
    • springcloud 整合 openfeign的方法
      目录一、openfeign简介二、使用1、依赖2、配置文件  3、启动类 4、接口5、controller一、openfeign简介 Feign是Nef...
      99+
      2024-04-02
    • SpringBoot整合tkMapper的方法
      SpringBoot整合tkMapper 项目使用SpringBoot2.0,H2数据库,使用了 Lombok 简化代码;本人是刚入门的菜鸟,下面是本人使用SpringBoot整合t...
      99+
      2022-11-13
      SpringBoot整合tkMapper SpringBoot tkMapper SpringBoot tkMapper使用
    • PHP整合php7特性的方法
      这篇文章主要介绍PHP整合php7特性的方法,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!PHP7 已经出来1年了,PHP7.1也即将和大家见面,这么多好的特性,好的方法,为什么不使用呢,也希望PHP越来越好。 在...
      99+
      2023-06-14
    • SpringBoot整合Shiro的方法详解
      目录1.Shito简介1.1 什么是shiro1.2 有哪些功能2.QuickStart3.SpringBoot中集成1.导入shiro相关依赖2.自定义UserRealm3.定义s...
      99+
      2024-04-02
    • JWT整合Springboot的方法步骤
      目录1.基于JWT认证1.1 认证流程1.2 JWT优势1.3 JWT的结构是什么2.使用JWT3.整合Springboot1.基于JWT认证 1.1 认证流程 首先,前...
      99+
      2024-04-02
    • Springboot redis整合配置的方法
      本文小编为大家详细介绍“Springboot redis整合配置的方法”,内容详细,步骤清晰,细节处理妥当,希望这篇“Springboot redis整合配置的方法”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。1...
      99+
      2023-06-19
    • maven grpc整合springboot demo的方法
      这篇文章主要介绍了maven grpc整合springboot demo的方法的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇maven grpc整合springboot ...
      99+
      2023-06-30
    • springBoot整合rabbitMQ的方法详解
      引入pom <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://mave...
      99+
      2024-04-02
    • SpringBoot整合mybatis的方法详解
      目录1 依赖配置2 使用2.1 SpringBoot配置整合mybatis:2.2 SpringBoot注解整合mybatis:2.3 在配置类上增加@MapperScan注解,扫描...
      99+
      2024-04-02
    • springboot整合mybatisplus的方法详解
      目录POM:application.yaml:POJO:mapper接口:包扫描:测试:总结POM: <dependency> <groupId>com....
      99+
      2024-04-02
    软考高级职称资格查询
    编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
    • 官方手机版

    • 微信公众号

    • 商务合作