设计模式之模板方法模式-解析binlog

binlog中记录数据的增、删、改操作;用模板方法模式和静态工厂模式来处理binlog解析

依赖

<dependency>
    <groupId>com.zendesk</groupId>
    <artifactId>mysql-binlog-connector-java</artifactId>
    <version>0.25.5</version>
</dependency>

获取binlog文件进行解析

public class Test {

    /**
     * bin文件前缀
     */
    private static final String filePrefix = "mysql-bin";

    public static void main(String[] args) {
        // 获取前缀为mysql-bin开头的,并且不是.index的文件
        File[] logFiles = new File("D:/logs/binlog/").listFiles((f, name) -> {
            String suffix = name.substring(name.indexOf(".") + 1);
            return name.startsWith(filePrefix) && !"index".equals(suffix);
        });
        for(File f:logFiles) {
            EventDeserializer eventDeserializer = new EventDeserializer();
            eventDeserializer.setCompatibilityMode(
                    EventDeserializer.CompatibilityMode.DATE_AND_TIME_AS_LONG,
                    EventDeserializer.CompatibilityMode.CHAR_AND_BINARY_AS_BYTE_ARRAY
            );
            try (
                BinaryLogFileReader bfr = new BinaryLogFileReader(f, eventDeserializer);
            ) {
                for (Event event; (event = bfr.readEvent()) != null; )
                    // 使用静态工厂创建解析实例
                    BinlogEventFactory.executeAnalysis(event);

            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

使用工厂模式,根据操作类型创建对应实例

public class BinlogEventFactory {

    public static void executeAnalysis(Event event) throws Exception {
        if(TableMapEventData.class.isInstance(event.getData())) {
            new TableMapEventAnalysis().analysis(event);
        } else if(EventType.isDelete(event.getHeader().getEventType())) {
            // 删除操作
            new DeleteEventAnalysis().analysis(event);
        } else if(EventType.isUpdate(event.getHeader().getEventType())) {
            // 更新操作
            new UpdateEventAnalysis().analysis(event);
        } else if(EventType.isWrite(event.getHeader().getEventType())) {
            // 保存操作
            new SaveEventAnalysis().analysis(event);
        }
    }
}

接口

public interface BinlogService {

    void analysis(Event event) throws Exception;
}

用来处理表信息的实现

public class TableMapEventAnalysis implements BinlogService {

    @Override
    public void analysis(Event event) {
        TableMapEventData tableMapEventData = event.getData();
        // 需要将tableId与table的关系存下来方便获取表名
        System.out.println(tableMapEventData.getTable() + ":" + tableMapEventData.getTableId());
    }
}

通过一个抽象类来定义我们的模板

将公共代码放入模板中,并提供一个具体处理的抽象方法供子类实现

public abstract class BinlogServiceImpl implements BinlogService {

    protected String tableName;

    protected List<String> rows;

    @Override
    public void analysis(Event event) throws Exception {

        // binlog中没有表名,只有TableMapEventData中才有表名
        long tableId = getTableId(event.getData());
        // 可以根据table获取到表名
        tableName = "获取到的表名";

        // binlog中没有具体的列,只有列的位置如:0,1,2,3,可以根据表名查询表的所有字段
        // 可以通过 show columns from table 事先查询字段放入缓存
        rows = Arrays.asList("获取到的字段列表");

        System.out.println("必要信息初始完成");

        handle(event);
    }

	// 具体处理方法
    protected abstract void handle(Event event);

    private long getTableId(EventData data) throws Exception {
        Class<?> clazz = data.getClass();
        Method method = clazz.getMethod("getTableId");
        if(null == method) {
            return -1;
        }
        return (long) method.invoke(data);
    }
}

所有增、删、改操作均继承抽象类;此时只需要关心自己本身需要的操作即可

添加数据

public class SaveEventAnalysis extends BinlogServiceImpl {

    @Override
    protected void handle(Event event) {
        WriteRowsEventData eventData = event.getData();
        System.out.println("插入数据操作,表:" + tableName + ", 列:" + String.join(",", rows));
    }
}

修改数据

public class UpdateEventAnalysis extends BinlogServiceImpl {

    @Override
    protected void handle(Event event) {
        UpdateRowsEventData updateRowsEventData = event.getData();
        System.out.println("更新数据操作,表:" + tableName + ", 列:" + String.join(",", rows));
    }
}

删除数据

public class DeleteEventAnalysis extends BinlogServiceImpl {

    @Override
    protected void handle(Event event) {
        DeleteRowsEventData eventData = event.getData();
        System.out.println("删除数据操作,表:" + tableName + ", 列:" + String.join(",", rows));
    }
}

测试效果

在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值