1. 程式人生 > >PSQLException:ERROR: value too long for type character(1)

PSQLException:ERROR: value too long for type character(1)

java使用mybatis的typehandler處理char型別的enum 傳值進資料庫的時候出現這個情況:

資料庫拿出來的時候enum 轉型是沒有問題的,傳入資料庫的時候出現這個問題

附一下程式碼:

public enum Flag {

    ACTIVE('a'),
    INACTIVE('i'),
    DUPLICATED('d'),
    PURGE('p')
    ;

    private char value;

    public static Flag findByValue(char value) {
        for (Flag flag : values()) {
            if (flag.getValue() == value) {
                return flag;
            }
        }
        return null;
    }

    Flag(char value) {
        this.value = value;
    }

    public final char getValue() {
        return this.value;
    }

}
public class FlagTypeHandler extends BaseTypeHandler<Enum<Flag>> {

    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, Enum<Flag> flag, JdbcType jdbcType) throws SQLException {
        ps.setString(i,flag.name());
    }

    @Override
    public Enum<Flag> getNullableResult(ResultSet rs, String columnName) throws SQLException {
        char value = rs.getString(columnName).charAt(0);
        return Flag.findByValue(value);
    }

    @Override
    public Enum<Flag> getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
        char value = rs.getString(columnIndex).charAt(0);
        return Flag.findByValue(value);
    }

    @Override
    public Enum<Flag> getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
        char value = cs.getString(columnIndex).charAt(0);
        return Flag.findByValue(value);
    }

}

1.把資料庫的char(1) 改成 char(255),傳入"ACTIVE",成功,但是資料庫儲存的是"ACTIVE",顯然typeHandler解析錯誤

2.仔細看一下程式碼,是在 "ps.setString(i,flag.name());" 這裡出錯,修改成:

ps.setString(i,String.valueOf(flag.name().charAt(0)));

試了一下,傳入ACTIVE ,沒有報錯,資料庫變成A

不對勁,看了一下,上面這個是取了name第一個字母,應該取得是value

3. 再修改

 ps.setString(i,Character.toString(Flag.valueOf(flag.name()).getValue()));

再次測試,傳入"ACTIVE" 資料庫存放"a",成功

4.貼一下最終改好的程式碼

public class FlagTypeHandler extends BaseTypeHandler<Enum<Flag>> {

    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, Enum<Flag> flag, JdbcType jdbcType) throws SQLException {
        ps.setString(i, Character.toString(Flag.valueOf(flag.name()).getValue()));
    }

    @Override
    public Enum<Flag> getNullableResult(ResultSet rs, String columnName) throws SQLException {
        return Optional.ofNullable(rs.getString(columnName)).flatMap(s -> Optional.ofNullable(Flag.findByValue(s.charAt(0)))).orElse(null);
    }

    @Override
    public Enum<Flag> getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
        return Optional.ofNullable(rs.getString(columnIndex)).flatMap(s -> Optional.ofNullable(Flag.findByValue(s.charAt(0)))).orElse(null);
    }

    @Override
    public Enum<Flag> getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
        return Optional.ofNullable(cs.getString(columnIndex)).flatMap(s -> Optional.ofNullable(Flag.findByValue(s.charAt(0)))).orElse(null);
    }

}

5.總結

對typeHandler 不熟悉導致 解析的時候寫錯了,要取的 value 寫成name。特別感謝老大幫忙,耶