DB2-Db2DefaultValueConverter
提示:
Db2DefaultValueConverter类的核心作用是在 Debezium 数据库连接器中处理 IBM DB2 数据库表列的默认值。当 Debezium 监控 DB2 数据库的更改时,它需要能够正确地理解和表示数据库表中列的默认值,尤其是在没有明确值的情况下插入新行时。
文章目录
- 前言
- 一、核心功能
- 二、代码分析
- 总结
前言
提示:Db2DefaultValueConverter 确保了 Debezium 在捕获和传播 DB2 数据库更改时的准确性,特别是在处理默认值时。这对于数据一致性至关重要,因为默认值可能会影响下游数据处理逻辑。
提示:以下是本篇文章正文内容
一、核心功能
核心功能详细说明
1. 初始化与构造
- Db2DefaultValueConverter 构造器: - 接收 Db2ValueConverters和Db2Connection对象作为参数。
- 初始化 defaultValueMappers映射,该映射包含对各种数据类型支持的DefaultValueMapper实例。这些实例负责解析和转换默认值。
 
- 接收 
2. 默认值解析
- parseDefaultValue方法:- 接收 Column对象和默认值字符串作为输入。
- 根据列的数据类型查找相应的 DefaultValueMapper。
- 使用找到的 DefaultValueMapper解析默认值表达式。
- 如果解析成功,调用 convertDefaultValue方法进行进一步转换;如果解析失败或类型不匹配,则返回Optional.empty()。
 
- 接收 
3. 默认值转换
- convertDefaultValue方法:- 接收解析后的默认值和 Column对象。
- 如果配置了 valueConverters并且默认值非空,则尝试使用valueConverters将默认值转换为 Kafka Connect 的 Schema 兼容格式。
- 如果转换失败或不需要转换,则直接返回默认值。
 
- 接收解析后的默认值和 
4. 默认值映射器创建
- createDefaultValueMappers方法:- 创建并返回一个 Map,其中键是 JDBC 数据类型,值是对应的DefaultValueMapper。
- 注册了对多种数据类型的支持,包括但不限于数值类型、日期/时间类型、字符和 Unicode 字符串类型。
- 每个注册的 DefaultValueMapper都是一个策略,用于处理特定类型数据的默认值解析。
 
- 创建并返回一个 
5. 特殊处理
- nullableDefaultValueMapper方法:- 提供一种处理可为空默认值的方式,允许将 "NULL"字符串转换为 Java 的null值。
 
- 提供一种处理可为空默认值的方式,允许将 
- booleanDefaultValueMapper方法:- 专门用于解析布尔类型的默认值,将 "1"和"0"分别转换为true和false。
 
- 专门用于解析布尔类型的默认值,将 
- castTemporalFunctionCall方法:- 用于处理日期和时间类型的默认值,特别是当前日期、时间和时间戳的函数调用。
 
6. 异常与日志处理
- 日志记录: - 使用 SLF4J 日志框架记录信息和警告级别的消息,例如解析过程的信息和未找到映射器的警告。
 
二、代码分析
package io.debezium.connector.db2;import java.sql.Time;
import java.sql.Timestamp;
import java.sql.Types;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;import org.apache.kafka.connect.data.Field;
import org.apache.kafka.connect.data.Schema;
import org.apache.kafka.connect.data.SchemaBuilder;
import org.apache.kafka.connect.data.Struct;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;import io.debezium.DebeziumException;
import io.debezium.jdbc.JdbcConnection;
import io.debezium.relational.Column;
import io.debezium.relational.DefaultValueConverter;
import io.debezium.relational.ValueConverter;
import io.debezium.util.Strings;/*** Converter for table column's default values.* 该类用于转换数据库表列的默认值。** @author Chris Cranford*/
public class Db2DefaultValueConverter implements DefaultValueConverter {private static final Logger LOGGER = LoggerFactory.getLogger(Db2DefaultValueConverter.class);// 日志记录器,用于输出调试和警告信息private final Db2ValueConverters valueConverters;// Db2ValueConverters 实例,用于类型转换private final Map<Integer, DefaultValueMapper> defaultValueMappers;// 存储不同数据类型对应的默认值映射器// 构造器,初始化 Db2ValueConverters 和 defaultValueMapperspublic Db2DefaultValueConverter(Db2ValueConverters valueConverters, Db2Connection jdbcConnection) {this.valueConverters = valueConverters;this.defaultValueMappers = Collections.unmodifiableMap(createDefaultValueMappers(jdbcConnection));}// 解析并返回给定列的默认值@Overridepublic Optional<Object> parseDefaultValue(Column column, String defaultValue) {LOGGER.info("Parsing default value for column '{}' with expression '{}'", column.name(), defaultValue);// 获取列的 JDBC 数据类型final int dataType = column.jdbcType();// 从 defaultValueMappers 中获取对应数据类型的 DefaultValueMapperDefaultValueMapper mapper = defaultValueMappers.get(dataType);// 如果未找到映射器,检查是否为 DECIMAL FLOAT 类型if (mapper == null) {if (dataType == Types.OTHER) {if (Db2ValueConverters.matches(column.typeName().toUpperCase(), "DECFLOAT")) {mapper = nullableDefaultValueMapper();}}// 如果仍然未找到映射器,输出警告并返回空 Optionalif (mapper == null) {LOGGER.warn("Mapper for type '{}' not found.", dataType);return Optional.empty();}}// 尝试解析默认值try {Object rawDefaultValue = mapper.parse(column, defaultValue != null ? defaultValue.trim() : defaultValue);// 转换默认值Object convertedDefaultValue = convertDefaultValue(rawDefaultValue, column);// 如果转换后的默认值是 Struct 类型,输出警告并返回空 Optionalif (convertedDefaultValue instanceof Struct) {LOGGER.warn("Struct can't be used as default value for column '{}', will use null instead.", column.name());return Optional.empty();}// 返回转换后的默认值return Optional.ofNullable(convertedDefaultValue);}// 捕获并处理解析异常catch (Exception e) {LOGGER.warn("Cannot parse column default value '{}' to type '{}'.  Expression evaluation is not supported.", defaultValue, dataType, e);LOGGER.debug("Parsing failed due to error", e);return Optional.empty();}}// 转换默认值private Object convertDefaultValue(Object defaultValue, Column column) {// 如果 valueConverters 不为空且默认值不为空,则进行转换if (valueConverters != null && defaultValue != null) {final SchemaBuilder schemaBuilder = valueConverters.schemaBuilder(column);if (schemaBuilder != null) {final Schema schema = schemaBuilder.build();// 创建 Field 实例final Field field = new Field(column.name(), -1, schema);// 获取 ValueConverter 实例final ValueConverter valueConverter = valueConverters.converter(column, field);// 使用 ValueConverter 转换默认值return valueConverter.convert(defaultValue);}}// 如果不需要转换,直接返回默认值return defaultValue;}// 创建 defaultValueMappers 映射private static Map<Integer, DefaultValueMapper> createDefaultValueMappers(Db2Connection connection) {final Map<Integer, DefaultValueMapper> result = new HashMap<>();// 注册支持的数据类型及其对应的 DefaultValueMapperresult.put(Types.BOOLEAN, nullableDefaultValueMapper(booleanDefaultValueMapper()));result.put(Types.BIGINT, nullableDefaultValueMapper());// ... 其他数据类型 ...// 返回不可修改的映射return result;}// 创建可处理 NULL 的 DefaultValueMapperprivate static DefaultValueMapper nullableDefaultValueMapper() {return nullableDefaultValueMapper(null);}// 创建可处理 NULL 和自定义映射的 DefaultValueMapperprivate static DefaultValueMapper nullableDefaultValueMapper(DefaultValueMapper mapper) {return (column, value) -> {if ("NULL".equalsIgnoreCase(value)) {return null;}if (mapper != null) {return mapper.parse(column, value);}return value;};}// 创建用于布尔类型的 DefaultValueMapperpublic static DefaultValueMapper booleanDefaultValueMapper() {return (column, value) -> {if ("1".equals(value.trim())) {return true;}else if ("0".equals(value.trim())) {return false;}return Boolean.parseBoolean(value.trim());};}// 创建用于日期和时间类型的 DefaultValueMapperprivate static DefaultValueMapper castTemporalFunctionCall(Db2Connection connection, int jdbcType) {return (column, value) -> {// 如果默认值为 CURRENT DATE 或 CURRENT TIME 或 CURRENT TIMESTAMP// ... 处理逻辑 ...// 否则,执行 SQL 查询以解析默认值// ... 查询逻辑 ...};}// 创建用于强制填充字符字段的 DefaultValueMapperprivate static DefaultValueMapper enforceCharFieldPadding() {return (column, value) -> value != null ? Strings.pad(unquote(value), column.length(), ' ') : null;}// 创建用于强制取消引用字符串的 DefaultValueMapperprivate static DefaultValueMapper enforceStringUnquote() {return (column, value) -> value != null ? unquote(value) : null;}// 取消引用字符串private static String unquote(String value) {// 如果字符串以 '(' 开头且以 ')' 结尾,则去掉引号// 如果字符串以单引号开头且以单引号结尾,则去掉引号// 否则,直接返回原字符串return value;}
}Db2DefaultValueConverter 类的设计体现了面向对象编程的几个关键原则和模式,包括封装、继承、多态、以及策略模式。
-  封装: - 封装是将数据和操作数据的方法绑定在一起,隐藏对象的属性和实现细节,仅对外暴露接口。Db2DefaultValueConverter封装了默认值解析和转换的逻辑,通过公共方法parseDefaultValue提供给外部调用,而具体的实现细节如defaultValueMappers映射和转换逻辑被隐藏在类内部。
 
- 封装是将数据和操作数据的方法绑定在一起,隐藏对象的属性和实现细节,仅对外暴露接口。
-  继承与多态: - 虽然 Db2DefaultValueConverter本身没有直接使用继承,但它依赖于DefaultValueMapper接口的多态性,不同的DefaultValueMapper实现可以根据具体的数据类型动态选择,这体现了多态的灵活性。
 
- 虽然 
-  策略模式: - 策略模式允许算法在运行时被替换,Db2DefaultValueConverter使用defaultValueMappers映射来实现这一模式,根据不同的数据类型动态选择合适的DefaultValueMapper实例,使得系统更加灵活和可扩展。
 
- 策略模式允许算法在运行时被替换,
设计亮点
-  模块化与解耦: - 通过将不同的数据类型映射到独立的 DefaultValueMapper实现,Db2DefaultValueConverter实现了高度的模块化和解耦。这意味着添加新的数据类型支持或修改现有类型的行为变得简单,只需添加或修改相应的DefaultValueMapper即可。
 
- 通过将不同的数据类型映射到独立的 
-  异常处理与日志记录: - 异常处理机制和日志记录的使用展示了良好的错误处理实践。当解析或转换默认值时遇到问题,Db2DefaultValueConverter不仅捕获异常,还记录详细的错误信息,有助于调试和维护。
 
- 异常处理机制和日志记录的使用展示了良好的错误处理实践。当解析或转换默认值时遇到问题,
-  可配置性与扩展性: - 通过接受 Db2ValueConverters和Db2Connection作为构造器参数,Db2DefaultValueConverter具备了很好的可配置性和扩展性。这允许在运行时动态调整其行为,适应不同的部署环境和需求。
 
- 通过接受 
启发
-  面向对象设计的灵活性: - Db2DefaultValueConverter的设计展示了面向对象设计的灵活性和可扩展性。通过策略模式和模块化设计,系统可以轻松应对未来的需求变化,无需对核心代码做重大修改。
 
-  代码复用与维护性: - 通过将通用的逻辑抽象为接口和类,如 DefaultValueMapper,代码变得更加易于复用和维护。这种设计鼓励重用现有的组件,减少重复代码,提高开发效率。
 
- 通过将通用的逻辑抽象为接口和类,如 
-  健壮性与错误处理: - 强调了异常处理和日志记录的重要性,确保了系统的健壮性和可维护性。即使在面对未知的错误或异常情况时,系统也能优雅地降级或恢复,同时提供足够的信息来诊断问题。
 
总结
提示:Db2DefaultValueConverter 是 Debezium 数据库连接器中的一个核心组件,专注于处理 IBM DB2 数据库表列的默认值解析和转换。其主要职责是确保在监控数据库变更事件时,能够正确识别和表示列的默认值,这对于数据同步和复制的准确性至关重要。
相关文章:
DB2-Db2DefaultValueConverter
提示:Db2DefaultValueConverter 类的核心作用是在 Debezium 数据库连接器中处理 IBM DB2 数据库表列的默认值。当 Debezium 监控 DB2 数据库的更改时,它需要能够正确地理解和表示数据库表中列的默认值,尤其是在没有明确值的情况下插入新行时。…...
 
(自适应手机端)行业协会机构网站模板
(自适应手机端)行业协会机构网站模板PbootCMS内核开发的网站模板,该模板适用于行业协会网站等企业,当然其他行业也可以做,只需要把文字图片换成其他行业的即可;自适应手机端,同一个后台,数据即时同步&#…...
 
视频理解调研笔记 | 2021年前视频动作分类发展脉络
前言 参考资料 本文基于以下四个李沐 AI 论文精度视频,对视频理解领域做初步调研 双流网络论文逐段精读 I3D 论文精读 视频理解论文串讲(上) 视频理解论文串讲(下) 相关论文 02014CVPRDeep VideoPDF12014NIPSTwo-Str…...
 
怎么通过 ssh 访问远程设备
文章目录 什么是 SSH背景环境配置前置准备在 linux 系统中安装 ssh 组件 什么是 SSH ssh 全称是 Secure Shell, 有时候也被叫做 Secure Socket Shell, 这个协议使你能通过命令行的方式安全的连接到远端计算机。当连接建立就会启动一个 shell 会话,这时你就能在你的…...
 
linux Ubuntu 安装mysql-8.0.39 二进制版本
我看到网上很多都写的乱七八糟, 我自己总结了一个 首先, 去Mysql官网上下载一个mysql-8.0.39二进制版本的安装包 这个你自己去下载我这里就写一个安装过程和遇到的坑 第一步 解压mysql压缩包和创建my.cnf文件 说明: 二进制安装指定版本MySQL的时候,需要手动写配置…...
 
ZooKeeper日志自动清理实用脚本
ZooKeeper日志自动清理:保持系统整洁的实用脚本 在管理ZooKeeper集群时,定期清理日志文件是一项重要但常被忽视的任务。本文将介绍一个简单而有效的bash脚本,用于自动清理ZooKeeper的日志和快照文件,并讨论如何使用cron来定期执行此脚本。 磁盘告警,所以写了一个脚…...
KVM+GFS分布式存储系统构建高可用
一:部署GFS高可用分布式存储环境 1:安装部署 KVM 虚拟化平台 2:部署 GlusterFS 在所有节点上执行如下命令: (1)关闭防所有节点的防火墙、SELiunx systemctl stop firewalldsystemctl disable firewallds…...
 
CIFAR-10 数据集图像分类与可视化
数据准备 CIFAR-10 and CIFAR-100 datasets (toronto.edu)在上述网站中下载Python版本的CIFAR-10数据集。 下载后的压缩包解压后会得到几个文件如下: 对应的data_batch_1 ~ data_batch_5 是划分好的训练数据,每个文件里包含10000张图片,test…...
 
没有了高项!!2024软考下半年软考高级哪个最容易考过?
距离2024上半年软考考试结束已经有一段时间了,有不少小伙伴都在开始准备下半年软考了,值得注意的是:近日各省陆续公布了2024上半年软考合格名单。那么,软考高级通过率到底如何?先来看看吧! 一、上半年软考通…...
用户自定义Table API Connector(Sources Sinks)
目录 概述 Metadata Planning Runtime 扩展点 动态表工厂(Dynamic Table Factories) 动态表(Dynamic Table) 动态表源(Dynamic Table Source) 扫描表源(Scan Table Source) 查找表源(Lookup Table Source) 动态表接收器(Dynamic Table Sink) 编码/解码…...
 
自闭症儿童能否摘帽?摘帽成功的秘诀揭秘
自闭症,这一曾经被视为不可逆转的障碍,如今在科学的进步与社会的关注下,正逐步展现出被“摘帽”的可能性。那么,自闭症儿童真的能完全摆脱这一标签,实现真正的“摘帽”吗?答案是肯定的,关键在于…...
 
主题巴巴WordPress主题合辑打包下载+主题巴巴SEO插件
主题巴巴WordPress主题合辑打包下载,包含博客一号、博客二号、博客X、门户一号、门户手机版、图片一号、杂志一号、自媒体一号、自媒体二号和主题巴巴SEO插件。...
git把本地文件上传远程仓库的流程
下载git,并创建一个仓库,这里着重介绍怎么把本地文件上传参考 正确执行步骤:在你需要上传的文件夹空白处下,右键鼠标,点击git bash here $ git init初始化当前目录 $ git status看一下当前分支里面有什么,…...
 
基于springboot+vue+uniapp的养老院管理系统小程序
开发语言:Java框架:springbootuniappJDK版本:JDK1.8服务器:tomcat7数据库:mysql 5.7(一定要5.7版本)数据库工具:Navicat11开发软件:eclipse/myeclipse/ideaMaven包&#…...
el-popover实现点击空白区域关闭,弹窗区域不关闭
难点: 普通方法会无法关闭,虚拟触发会导致选一个关一个,不用visible显示的方法太麻烦。 所以结合其他人的方法,使用手动监听判断的方法(点击蓝色区域看参考,这大佬vue2的,我vue3) 注…...
Disjoint Set Union
Problem One : 维护区间连通块 F - Range Connect MST (atcoder.jp) 暴力模拟的话,就是基于 Kruskal 的思想,按 c c c 从小到大排序,对于每次询问,枚举检查 j ∈ [ l , r ] j\in [l,r] j∈[l,r] ,只要 j j j 与 …...
手写 Hibernate ORM 框架 05-基本效果测试
手写 Hibernate 系列 手写 Hibernate ORM 框架 00-hibernate 简介 手写 Hibernate ORM 框架 00-环境准备 手写 Hibernate ORM 框架 01-注解常量定义 手写 Hibernate ORM 框架 02-实体 Bean 定义,建表语句自动生成 手写 Hibernate ORM 框架 03-配置文件读取, 数…...
 
Unity材质球自动遍历所需贴图
Unity材质球自动遍历所需贴图 文章目录 Unity材质球自动遍历所需贴图一、原理二、用法1.代码:2.使用方法 一、原理 例如一个材质球名为:Decal_Text_Cranes_01_Mat , 然后从全局遍历出:Decal_Text_Cranes_01_Albedo赋值给材质球的…...
 
C++那些事之结构化绑定
C那些事之结构化绑定 在聊结构化绑定之前,有几个面试问题,看看你会不会? 如何使用结构化绑定访问自定义类的私有成员?如何使用结构化绑定修改自定义类的成员呢? 这几个题目估计没几个人能答上来,题目与答案…...
 
ECRS工时分析软件:工业工程精益生产的智慧引擎
在工业工程学的广阔领域中,程序分析一直扮演着至关重要的角色。其中,ECRS四大原则——取消、合并、重排、简化,作为程序分析的核心,旨在通过优化生产过程,实现成本的节省和精益生产的目标。如今,随着科技的…...
 
超短脉冲激光自聚焦效应
前言与目录 强激光引起自聚焦效应机理 超短脉冲激光在脆性材料内部加工时引起的自聚焦效应,这是一种非线性光学现象,主要涉及光学克尔效应和材料的非线性光学特性。 自聚焦效应可以产生局部的强光场,对材料产生非线性响应,可能…...
mongodb源码分析session执行handleRequest命令find过程
mongo/transport/service_state_machine.cpp已经分析startSession创建ASIOSession过程,并且验证connection是否超过限制ASIOSession和connection是循环接受客户端命令,把数据流转换成Message,状态转变流程是:State::Created 》 St…...
 
涂鸦T5AI手搓语音、emoji、otto机器人从入门到实战
“🤖手搓TuyaAI语音指令 😍秒变表情包大师,让萌系Otto机器人🔥玩出智能新花样!开整!” 🤖 Otto机器人 → 直接点明主体 手搓TuyaAI语音 → 强调 自主编程/自定义 语音控制(TuyaAI…...
在web-view 加载的本地及远程HTML中调用uniapp的API及网页和vue页面是如何通讯的?
uni-app 中 Web-view 与 Vue 页面的通讯机制详解 一、Web-view 简介 Web-view 是 uni-app 提供的一个重要组件,用于在原生应用中加载 HTML 页面: 支持加载本地 HTML 文件支持加载远程 HTML 页面实现 Web 与原生的双向通讯可用于嵌入第三方网页或 H5 应…...
 
深度学习习题2
1.如果增加神经网络的宽度,精确度会增加到一个特定阈值后,便开始降低。造成这一现象的可能原因是什么? A、即使增加卷积核的数量,只有少部分的核会被用作预测 B、当卷积核数量增加时,神经网络的预测能力会降低 C、当卷…...
 
招商蛇口 | 执笔CID,启幕低密生活新境
作为中国城市生长的力量,招商蛇口以“美好生活承载者”为使命,深耕全球111座城市,以央企担当匠造时代理想人居。从深圳湾的开拓基因到西安高新CID的战略落子,招商蛇口始终与城市发展同频共振,以建筑诠释对土地与生活的…...
 
AI+无人机如何守护濒危物种?YOLOv8实现95%精准识别
【导读】 野生动物监测在理解和保护生态系统中发挥着至关重要的作用。然而,传统的野生动物观察方法往往耗时耗力、成本高昂且范围有限。无人机的出现为野生动物监测提供了有前景的替代方案,能够实现大范围覆盖并远程采集数据。尽管具备这些优势…...
JavaScript 数据类型详解
JavaScript 数据类型详解 JavaScript 数据类型分为 原始类型(Primitive) 和 对象类型(Object) 两大类,共 8 种(ES11): 一、原始类型(7种) 1. undefined 定…...
Java详解LeetCode 热题 100(26):LeetCode 142. 环形链表 II(Linked List Cycle II)详解
文章目录 1. 题目描述1.1 链表节点定义 2. 理解题目2.1 问题可视化2.2 核心挑战 3. 解法一:HashSet 标记访问法3.1 算法思路3.2 Java代码实现3.3 详细执行过程演示3.4 执行结果示例3.5 复杂度分析3.6 优缺点分析 4. 解法二:Floyd 快慢指针法(…...
【HarmonyOS 5】鸿蒙中Stage模型与FA模型详解
一、前言 在HarmonyOS 5的应用开发模型中,featureAbility是旧版FA模型(Feature Ability)的用法,Stage模型已采用全新的应用架构,推荐使用组件化的上下文获取方式,而非依赖featureAbility。 FA大概是API7之…...
