You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用MyBatis插入PostgreSQL bit(n)字段(对应Java byte[])报错求助

解决PostgreSQL bit(n)与Java byte[]的MyBatis Plus映射问题

问题回顾

向PostgreSQL插入数据时,因bit(n)字段与Javabyte[]类型不匹配报错:

org.postgresql.util.PSQLException: error: column "role" type is bit, but type of expression is bytea.

后续尝试自定义TypeHandler后,报错变为:

org.postgresql.util.PSQLException: error: column "role" type is bit, but type of expression is character varying.

核心原因

PostgreSQL的bit(n)类型需要传入固定长度的二进制格式字符串(如bit(2)对应'01'),但MyBatis默认将byte[]映射为bytea类型;错误的TypeHandler则将其转成了普通字符串,导致类型不匹配。

解决方案

1. 编写正确的TypeHandler

实现BaseTypeHandler,完成byte[]与PostgreSQLbit(n)的双向转换:

import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import java.sql.*;

public class BitByteArrayTypeHandler extends BaseTypeHandler<byte[]> {

    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, byte[] parameter, JdbcType jdbcType) throws SQLException {
        // 获取字段的bit长度(如bit(2)提取出2)
        ParameterMetaData metaData = ps.getParameterMetaData();
        String typeName = metaData.getParameterTypeName(i);
        int bitLength = Integer.parseInt(typeName.substring(4, typeName.length() - 1));

        // 将byte转成对应长度的二进制字符串
        StringBuilder bitStrBuilder = new StringBuilder();
        int value = parameter[0] & 0xFF; // 取第一个byte的无符号值
        for (int j = bitLength - 1; j >= 0; j--) {
            bitStrBuilder.append((value >> j) & 1);
        }

        ps.setString(i, bitStrBuilder.toString());
    }

    @Override
    public byte[] getNullableResult(ResultSet rs, String columnName) throws SQLException {
        return parseBitStrToByte(rs.getString(columnName));
    }

    @Override
    public byte[] getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
        return parseBitStrToByte(rs.getString(columnIndex));
    }

    @Override
    public byte[] getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
        return parseBitStrToByte(cs.getString(columnIndex));
    }

    // 将数据库返回的bit字符串转成byte[]
    private byte[] parseBitStrToByte(String bitStr) {
        if (bitStr == null) {
            return null;
        }
        int value = Integer.parseInt(bitStr, 2);
        return new byte[]{(byte) value};
    }
}

2. 配置DO类字段

在role和module字段上指定TypeHandler:

@TableName("agri_person_relation")
@KeySequence("agri_person_relation_seq") 
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class PersonRelationDO extends BaseDO {
    @TableId
    private Long id;

    private Long relatedTableId;

    @TableField(typeHandler = BitByteArrayTypeHandler.class)
    private byte[] role;

    @TableField(typeHandler = BitByteArrayTypeHandler.class)
    private byte[] module;

    private Long personId;
}

3. 注册TypeHandler

确保MyBatis Plus能扫描到TypeHandler,有两种方式:

  • 配置文件方式(application.yml):
mybatis-plus:
  type-handlers-package: com.yourproject.handler # 替换为TypeHandler所在包路径
  • 代码配置方式:
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.baomidou.mybatisplus.core.MybatisConfiguration;
import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean;

@Configuration
@MapperScan("com.yourproject.mapper")
public class MyBatisPlusConfig {

    @Bean
    public MybatisSqlSessionFactoryBean sqlSessionFactory() {
        MybatisSqlSessionFactoryBean factoryBean = new MybatisSqlSessionFactoryBean();
        // 配置数据源等其他信息...
        
        MybatisConfiguration configuration = new MybatisConfiguration();
        configuration.getTypeHandlerRegistry().register(BitByteArrayTypeHandler.class);
        factoryBean.setConfiguration(configuration);
        
        return factoryBean;
    }
}

验证逻辑

  • 插入时:byte[] role = new byte[]{1}(二进制00000001)会被转成'01',匹配bit(2)字段类型。
  • 查询时:数据库返回的'01'会被转成byte[]{1},实现双向兼容。

内容的提问来源于stack exchange,提问作者Paul

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 23:05:06