postgresql的bit(3)和java byte[3] mybatis转换

如题,想着写个typehandler来处理下对应关系

img


挂在了mapper里

img


还是报一样的错误

img

结个题吧,这个问题暂时看来没有解决方法。jdbc.BIT 对应的是 PostgreSQL 的 bit(1) 而 没有 类与 bit(n) 对应。所以使用TypeHandler 是解决不了应该。可能还是得回去手写sql或者把字段类型改了。

bit 对应 Boolean

以下答案由GPT-3.5大模型与博主波罗歌共同编写:
PostgreSQL中的bit(3)和Java中的byte[3]有一定的类型差异,因此我们需要使用MyBatis中的TypeHandler来进行转换。

首先,我们需要自定义一个TypeHandler类,实现其中的getNullableResult和setNonNullParameter方法来进行类型转换。具体代码如下:

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

public class BitToByteArrayTypeHandler extends BaseTypeHandler<byte[]> {
    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, byte[] parameter, JdbcType jdbcType) throws SQLException {
        // 将byte数组转换为PostgreSQL的bit类型
        String bitStr = "";
        for (byte b : parameter) {
            int num = (int) b & 0xFF;
            bitStr += Integer.toBinaryString(num);
        }
        while (bitStr.length() < 24) {
            bitStr = "0" + bitStr;
        }
        ps.setObject(i, "B'" + bitStr + "'", JdbcType.OTHER);
    }

    @Override
    public byte[] getNullableResult(ResultSet rs, String columnName) throws SQLException {
        // 将PostgreSQL的bit类型转换为byte数组
        String bitStr = rs.getString(columnName);
        if (bitStr != null) {
            bitStr = bitStr.replaceFirst("^B'", "").replaceFirst("'$", "");
            if (bitStr.length() != 24) {
                throw new TypeException("Error converting Bit to byte[] - " + bitStr + " has length other than 24");
            }
            int unused_bits = bitStr.charAt(0) - '0';
            int byteLen = 3;
            if (unused_bits == 0) {
                byteLen = 3;
            } else if (unused_bits == 1) {
                byteLen = 2;
            } else {
                byteLen = 1;
            }
            byte[] result = new byte[byteLen];
            for (int i = 0; i < byteLen; i++) {
                result[i] = (byte) Integer.parseInt(bitStr.substring(i * 8 + unused_bits, i * 8 + 8 + unused_bits), 2);
            }
            return result;
        } else {
            return null;
        }
    }

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

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

然后,在MyBatis的Mapper XML文件中,我们需要使用typeHandler来引用刚刚自定义的TypeHandler类,如下所示:

<resultMap id="resultMap" type="com.example.demo.entity.TableEntity">
    <id property="id" column="id" />
    <result property="bitArray" column="bit_array" typeHandler="com.example.demo.handler.BitToByteArrayTypeHandler" />
    ...
</resultMap>

<select id="selectById" resultMap="resultMap">
    SELECT * FROM table WHERE id = #{id}
</select>

更进一步的,通过在代码中使用@Result注解和@Select注解来代替*Mapper XML文件来配置TypeHandler,如下所示:

@Mapper
public interface TableMapper {
    @Results(id = "tableResultMap", value = {
        @Result(column = "id", property = "id"),
        @Result(column = "bit_array", property = "bitArray", typeHandler = BitToByteArrayTypeHandler.class),
        ...
    })
    @Select("SELECT * FROM table WHERE id = #{id}")
    TableEntity selectById(int id);
}

如果我的回答解决了您的问题,请采纳!

Mybatis数据库数据类型和Java数据类型之间转换

可以借鉴下

https://blog.csdn.net/jaemy2011/article/details/125073639

该回答通过自己思路及引用到GPTᴼᴾᴱᴺᴬᴵ搜索,得到内容具体如下:
根据您提供的信息,您可以编写一个自定义的TypeHandler来处理PostgreSQL的bit类型和Java的byte[]类型之间的转换。

以下是一个示例TypeHandler的代码:

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

@MappedTypes(byte[].class)
@MappedJdbcTypes(JdbcType.BIT)
public class PostgresBitTypeHandler extends BaseTypeHandler<byte[]> {

    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, byte[] parameter, JdbcType jdbcType) throws SQLException {
        ps.setObject(i, parameter);
    }

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

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

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

在上面的代码中,我们定义了一个名为PostgresBitTypeHandler的TypeHandler,它将PostgreSQL的bit类型映射到Java的byte[]类型。我们使用@MappedTypes@MappedJdbcTypes注解来指定类型映射关系。

setNonNullParameter方法中,我们将Java的byte[]类型转换为PostgreSQL的bit类型,并将其设置为PreparedStatement的参数。

getNullableResult方法中,我们将从ResultSet或CallableStatement中获取的PostgreSQL的bit类型转换为Java的byte[]类型,并返回它。

请注意,由于PostgreSQL的bit类型与Java的byte[]类型之间的转换可能不是一一对应的,因此您需要根据具体情况进行微调。

另外,您需要在mybatis配置文件中注册TypeHandler,例如:

<typeHandlers>
    <typeHandler handler="com.example.PostgresBitTypeHandler"/>
</typeHandlers>

在上面的代码中,com.example.PostgresBitTypeHandler是您自定义的TypeHandler类的完整类名。

希望这可以帮助您解决问题。


如果以上回答对您有所帮助,点击一下采纳该答案~谢谢