2009-11-20 131 views
6

我放置和图像到数据库中,它可能是MYSQL数据库(服务器)或SQLITE数据库(用于旅途中的平板电脑)。 Java应用程序每天与服务器同步,上传新数据并下载任何新数据。那部分工作正常。但是,它的要求是它也能够处理图像。Java异常错误 - Sqlite preparedStatement.setBlob

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

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

我的测试程序在字符串和字节数组之间来回转换(最终是图像)没问题。所以我相信这个问题是在准备声明中设置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(); 
    } 

} 

任何帮助不胜感激。

回答

0

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

+0

不知道如果可能的话,count在ByteArrayInputStream内受保护,那么我将如何访问它。 Secondaly我以为流只有一个字节在任何时候?我仍然试图将我的头围绕在这个过程上,所以我可以离开基地。 – Peter 2009-11-20 06:40:33

7

根据a recent post Xerial group setBlob方法没有在sqlite-jdbc中实现。对我来说,所提出的替代

preparedStatement.setBytes(idx, data)

工作得很好,如果你的二进制数据是足够小,加载到内存中的字节数组。

+0

救了我!我只有5分钟的时间来解决问题,这就是它! – 2013-05-10 15:53:21