【问题标题】:Java Exception Error - Sqlite preparedStatement.setBlobJava 异常错误 - SqlitepreparedStatement.setBlob
【发布时间】:2010-12-18 14:04:05
【问题描述】:

我正在将图像放入数据库,它可以是 MYSQL 数据库(服务器)或 SQLITE 数据库(用于路上的平板电脑)。 Java 应用程序每天与服务器同步,上传新数据并下载任何新数据。那部分运作良好。但是,要求它也能够处理图像。

我们选择在数据库中使用 blob,而不是实现一个依赖于将图像复制到每一端的文件系统的全新系统。对说不要这样做的响应并不真正感兴趣;)我真正需要帮助的是,当我尝试编写 blob 时,我在调度中遇到异常。

我们正在从数据库构建输入表单,因为整个应用程序用于不同的目的,具体取决于数据库。输入表单允许您将图像附加到记录,我们将其存储为 base64 字符串。然后解码成一个byte[]。

我的测试程序在字符串和字节数组(最终是图像)之间来回转换没有问题。所以我相当确信问题在于在准备好的语句中设置 Blob,但我可能是错的。

点击保存按钮后出现异常。

Exception occurred during event dispatching:
java.lang.AbstractMethodError: org.sqlite.PrepStmt.setBlob(ILjava/io/InputStream;J)V
    at tabletapp.database.DB.prepareStatement(DB.java:641)
    at tabletapp.database.DB.save(DB.java:743)
    at tabletapp.FormPanel.saveData(FormPanel.java:546)

有问题的代码块

public void prepareStatement(String table, String sql, LinkedHashMap<String, String> data) {
    try {
        String typeID = "";
        PreparedStatement ps = connection.prepareStatement(sql);
        log.debug("Preparing SQL: " + sql.replace("\n", ""));
        int parameterIndex = 1;

        //for (String columnName : getColumnNames(table)) {
        for (String columnName : data.keySet()) {
            typeID = getColumnType(table, columnName);

            if (data.containsKey(columnName)) {
                String value = data.get(columnName);
                if (value == null || "".equals(value)) {
                    //log.debug(columnName+":"+parameterIndex+" set to null");
                    ps.setNull(parameterIndex, Types.NULL);
                } else {
                    //log.debug(columnName+":"+parameterIndex+" set to "+value);
                    switch (getColumnTypeId(table, columnName)) {
                        case Types.VARCHAR:
                        case Types.CHAR:
                            ps.setString(parameterIndex, value);
                            break;

                        case Types.TIMESTAMP:
                            DateFormat timestampFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                            java.util.Date timstamp = new java.util.Date();
                            ps.setString(parameterIndex, timestampFormat.format(timstamp));
                            break;

                        case Types.DATE:
                            DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
                            java.util.Date date = new java.util.Date();
                            ps.setString(parameterIndex, dateFormat.format(date));
                            break;

                        case Types.SMALLINT:
                        case Types.INTEGER:
                        case Types.NUMERIC:
                            ps.setInt(parameterIndex, new Integer(value));
                            break;

                        case Types.FLOAT:
                            ps.setFloat(parameterIndex, new Float(value));
                            break;

                        case Types.BLOB:
                            // convert string to byte array to blob
                            byte[] bData = null;
                            try {
                               bData = new BASE64Decoder().decodeBuffer(value);
                               log.info("I have Bytes[]");
                            }
                            catch (Exception e){
                                log.info("Something went Horribly, Horribly Wrong");
                            }

                            // Note tried the follwowing
                            //Blob blob=connection.createBlob();
                            // blob.setBytes(bData.length, bData);
                            // ps.setBlob(parameterIndex,blob);

                            ByteArrayInputStream bais = new ByteArrayInputStream(bData);
                            ps.setBlob(parameterIndex, bais,bData.length);


                            break;

                        case Types.BOOLEAN:
                        case Types.BIT:
                            //log.debug(table + "." + columnName + " (boolean) = " + value);
                            if ("1".equals(value) || "true".equals(value)) {
                                ps.setBoolean(parameterIndex, true);
                            } else {
                                ps.setBoolean(parameterIndex, false);
                            }
                            break;
                    }
                }
                parameterIndex++;
            }
        }
        ps.executeUpdate();
        connection.commit();
    } catch (SQLException e) {
        log.error("Error in sql: " + sql);
        e.printStackTrace();
    }

}

非常感谢任何帮助。

【问题讨论】:

    标签: java mysql database exception sqlite


    【解决方案1】:

    根据a recent post Xerial group,sqlite-jdbc 中没有实现 setBlob 方法。对我来说,建议的替代方案

    preparedStatement.setBytes(idx, data)

    如果您的二进制数据足够小,可以作为字节数组加载到内存中,则效果很好。

    【讨论】:

    • 救了我!我只有 5 分钟的时间来解决问题,就是这样!
    【解决方案2】:

    尝试使用“count”字段来获取 ByteArrayInputStream 对象的长度,bais,而不是解码字符串的长度。

    【讨论】:

    • 不确定这是否可能,计数在 ByteArrayInputStream 中受到保护,所以我将如何访问它。其次,我认为流在任何时候都只有一个字节?我仍在努力真正了解这个过程,所以我可以远离基地。
    猜你喜欢
    • 2016-05-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-29
    • 2018-10-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多