簡體   English   中英

Java異常錯誤 - Sqlite preparedStatement.setBlob

[英]Java Exception Error - Sqlite preparedStatement.setBlob

我將數據放入數據庫,它可以是MYSQL數據庫(服務器)或SQLITE數據庫(路上的平板電腦)。 Java應用程序每天與服務器同步,上傳新數據並下載任何新數據。 那部分運作良好。 但是,要求它也能夠處理圖像。

我們選擇在數據庫中使用blob,而不是實現一個依賴於將圖像復制到每端文件系統的全新系統。 對那些不這樣做的回復並不感興趣;)我真正需要幫助的是當我嘗試編寫blob時,我在調度中得到一個異常。

我們正在從數據庫構造輸入表單,因為整個應用程序正在用於不同的目的,這取決於數據庫。 輸入表單允許您將圖像附加到記錄,我們將其存儲為base64字符串。 然后將其解碼為byte []。

我的測試程序在字符串和字節數組之間來回轉換(最終是一個Image)沒問題。 所以我相信問題是在准備好的聲明中設置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();
    }

}

任何幫助非常感謝。

根據最近發布的Xerial組 ,方法setBlob沒有在sqlite-jdbc中實現。 對我來說,建議的替代方案

preparedStatement.setBytes(idx, data)

如果您的二進制數據足夠小,可以作為字節數組加載到內存中,那么工作正常。

嘗試使用'count'字段來獲取ByteArrayInputStream對象的長度bais,而不是解碼字符串的長度。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM