Java-工作中首次遇到问题记录(一)Mysql Json类型

前端要求对上传的文件列表保存并返回文件信息对象的数组,后端把其作为 Mysql中Json数据类型进行保存。对数据库 Json 类型保存,并与List对象相互映射,需要相应一些不同的处理。项目采用 SpringBoot + Mybatis-plus
借助 AI编程(豆包),使用提示词,给出的答案都不是很简单。

​ 我们现在实现一种最间接的。当然需用使用Mybatis-plus的高级编程 QueryWrapper,若用 mybatis xml中写sql的模式,则需要进一步配置数据库表字段与类字段之间的映射,如果是一个大对象,为了一个json字段配置整个映射关系显得笨拙。

开始实现步骤:

①. 表字段为json类型

②. 创建一个FileInfo类

 /* 文件信息实体
 */
@Data
public class FileInfo {
    // 文件编码
    private String fileCode;
    // 文件名称
    private String fileName;
}

③. 对应数据表的类,如 Business 中有一个字段为 List<FileInfo> fileInfoList , 配上相应的 Json转换处理注解 @TableField(typeHandler =JacksonTypeHandler.class)@TableName(autoResultMap = true) 即可。

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.time.LocalDateTime;
import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;

/**
 * 业务主实体(对应t_business表)
 * ✅ 核心:autoResultMap = true
 */
@Data
@TableName(value = "t_business",autoResultMap = true) // 绑定数据库表名
public class Business {
    @TableId(type = IdType.AUTO) // 主键自增
    private Long id;
    // 业务名称
    private String bizName;
    // ✅ 关键:List数组字段
    TableField(typeHandler = JacksonTypeHandler.class)
    private List<FileInfo> fileInfoList;
    
   // 创建时间
    private LocalDateTime createTime;
}

④查询与保存必须通过 BaseMapper 继承的方法,即复杂查询使用 QueryWrapper 或 LambdaQueryWrapper (推荐)

有关这方面的知识请自行查阅相关文档即可。

<think>我们面临的核心问题是:Flink CDC在同步PostgreSQL的oid类型到Doris时,由于Flink CDC Connector for PostgreSQL可能不支持oid类型(或支持不完善),导致同步失败。oid类型是PostgreSQL内部用于表示对象标识符的整数类型,通常为4字节无符号整数。 根据引用[2]提到的Flink CDC yaml实现PG到Doris的数据同步,我们可以采用以下解决方案: ### 解决方案:通过Flink SQL转换oid类型 由于Flink CDC可能无法直接识别oid类型,我们可以将其转换为Doris兼容的类型(如BIGINT)。以下是具体步骤: #### 1. 在Flink SQL中显式定义源表结构 在Flink SQL中,我们可以手动定义PostgreSQL表的结构,将oid类型的列映射为BIGINT类型(因为oid本质上是4字节整数,但Doris没有直接对应的类型,用BIGINT足够存储)。 ```sql -- 创建PostgreSQL CDC源表,将oid列转为BIGINT CREATE TABLE pg_source ( id INT, -- 其他列... oid_col BIGINT, -- 原始类型为oid,这里映射为BIGINT PRIMARY KEY (id) NOT ENFORCED ) WITH ( 'connector' = 'postgres-cdc', 'hostname' = 'pg_host', 'port' = '5432', 'username' = 'pg_user', 'password' = 'pg_password', 'database-name' = 'your_db', 'schema-name' = 'public', 'table-name' = 'your_table', 'decoding.plugin.name' = 'pgoutput' ); ``` #### 2. 创建Doris Sink表 在Doris中,我们同样使用BIGINT类型来存储转换后的oid值: ```sql -- 创建Doris目标表 CREATE TABLE doris_sink ( id INT, -- 其他列... oid_col BIGINT ) COMMENT 'Doris Table for PostgreSQL Sync' DISTRIBUTED BY HASH(id) BUCKETS 10 PROPERTIES ( "replication_num" = "1" ); ``` #### 3. 定义Flink写入任务 通过INSERT语句将数据从PostgreSQL CDC表同步到Doris表: ```sql INSERT INTO doris_sink SELECT id, -- 其他列... oid_col -- 这里已经是BIGINT类型 FROM pg_source; ``` ### 替代方案:使用Flink DataStream API进行转换 如果使用YAML配置文件(如引用[2]所示)且需要更复杂的转换逻辑,可以通过DataStream API实现: ```java // 示例代码片段(Java) DataStream<RowData> sourceStream = PostgreSQLSource.<RowData>builder() .hostname("pg_host") .port(5432) .database("your_db") .schemaList("public") .tableList("your_table") .username("pg_user") .password("pg_password") .deserializer(new JsonDebeziumDeserializationSchema()) // 使用JSON格式解析 .build(); // 转换oid列为BIGINT DataStream<RowData> transformedStream = sourceStream.map(row -> { // 假设oid列在RowData中的位置是第2列(索引从0开始) long oidValue = row.getLong(1); // 直接获取为long类型(即BIGINT) // 创建新的RowData,将原行数据复制并替换oid列为转换后的值 GenericRowData newRow = new GenericRowData(row.getArity()); for (int i = 0; i < row.getArity(); i++) { if (i == 1) { // oid列的位置 newRow.setField(i, oidValue); } else { newRow.setField(i, row.getField(i)); } } return newRow; }); // 写入Doris transformedStream.sinkTo(DorisSink.sink( DorisSinkOptions.builder() .setFenodes("doris_fe:8030") .setUsername("doris_user") .setPassword("doris_pwd") .setTableIdentifier("target_db.doris_sink") .build() )); ``` ### 注意事项 1. **数据类型映射**: - PostgreSQL的`oid`类型在Flink CDC中可能被解析为`INT`或`BIGINT`,但为了确保安全,显式转换为`BIGINT`(因为Doris的`BIGINT`是8字节整数,完全容纳oid的4字节整数)。 - 如果表中有多个oid列,需要为每列执行相同的转换。 2. **历史数据同步**: - Flink CDC在首次启动时会读取PostgreSQL的全量数据(快照),此时oid列会自动转换为BIGINT类型,无需额外处理。 3. **元数据管理**: - 如果PostgreSQL表结构变更(如新增oid列),需同步更新Flink作业的源表和目标表定义。 4. **性能考虑**: - 对于大规模数据,建议在Flink作业中设置合适的并行度(参考引用[2]中YAML配置的并行度设置)。 ### 验证方法 在Doris中查询同步后的数据,确认oid列的值与PostgreSQL致: ```sql SELECT oid_col FROM doris_sink LIMIT 10; ``` ### 扩展:其他PostgreSQL特殊类型处理 如果遇到其他特殊类型(如`money`、`point`等),可采用类似策略: - 复杂类型(几何、网络地址)→ 转换为JSON字符串(STRING) - 枚举类型 → 字符串(STRING) - 数组类型JSON字符串或Doris的ARRAY类型(需Doris 1.2+支持) > **关键提示**:对于不支持的PostgreSQL类型,Flink CDC通常会将其转换为STRING类型。若遇到转换异常,可在Flink作业中通过`CAST(col AS STRING)`进行兜底处理[^2]。 --- ### §§相关问题§§ 1. 如何监控Flink CDC任务中oid类型转换的正确性? 2. 如果PostgreSQL的oid列包含空值(NULL),同步到Doris时会出现什么问题? 3. 除了oid类型,PostgreSQL还有哪些特殊类型需要特殊处理才能同步到Doris? 4. 如何实现PostgreSQL到Doris的整库同步(包含多个表)?</think>### PostgreSQL OID 类型同步到 Doris 的解决方案 #### 核心问题分析 PostgreSQL 的 `oid` 类型是内部对象标识符(32位无符号整数),而 Flink CDC 的 PostgreSQL 连接器默认可能无法正确处理此类型。根据引用[2]的架构设计,我们可通过类型转换解决此问题。 #### 完整解决方案 ##### 1. **类型转换策略** ```sql -- Flink SQL 显式类型转换 CREATE TABLE pg_source ( id INT, object_oid BIGINT, -- 将oid转换为BIGINT ... ) WITH ( 'connector' = 'postgres-cdc', 'hostname' = 'pg_host', ... ); ``` **原理说明**: - PostgreSQL 的 `oid` 本质是4字节无符号整数(范围 0~4,294,967,295) - Doris 使用 `BIGINT`(8字节有符号整数)可完全容纳其取值范围 - 通过 Flink SQL 的列映射实现自动类型转换 ##### 2. **YAML 配置示例(基于引用[2])** ```yaml source: type: postgres table-name: your_table column-transform: - name: object_oid # 原始oid列名 new-name: object_id # Doris中的新列名 type: BIGINT # 强制转换类型 sink: type: doris table: doris_table doris.column.mapping: "object_id=object_id" # 列映射 ``` ##### 3. **Doris 表定义 ```sql CREATE TABLE doris_table ( id INT, object_id BIGINT, -- 对应转换后的oid ... ) ENGINE=OLAP DISTRIBUTED BY HASH(id) BUCKETS 10; ``` #### 验证与调试步骤 1. **测试类型转换**: ```sql -- Flink SQL 验证查询 SELECT object_oid, TYPEOF(object_oid) FROM pg_source LIMIT 10; ``` 2. **错误处理配置**: ```yaml # 在YAML中添加容错配置 execution: runtime-mode: streaming checkpointing: interval: 30s fault-tolerance: fail-on-error: false # 允许跳过错误记录 ``` #### 替代方案(复杂场景) 若需保留原始OID语义,可转换为字符串: ```sql CREATE TABLE pg_source ( ... object_oid STRING -- CAST(oid AS VARCHAR) ) WITH (...); ``` ```sql -- Doris端 CREATE TABLE doris_table ( ... object_oid VARCHAR(20) ); ``` #### 性能优化建议 1. **批量写入**: ```yaml sink: batch.size: 5000 batch.interval: 10s ``` 2. **并行处理**: ```yaml parallelism.default: 4 # 根据CPU核心数调整 ``` > **关键提示**:PostgreSQL的OID在同步后可能失去其原始语义(如系统目录关联),若业务依赖此特性,需在Doris端通过额外字段维护元数据关系[^2]。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值