2014-07-05 33 views
2

我試圖將一個Java byte []插入到H2數據庫表中,然後再次檢索它,但是我沒有實現成功。根據this page,BINARY數據類型直接映射到byte []。所以我的理解是我可以將byte []變量直接寫入列,但是當我嘗試再次檢索時導致異常。將Java byte []對象插入到H2表中,然後再次檢索它

這是一個說明我的問題的SSCCE。我在這裏做錯了什麼?

PS:您需要安裝H2 database才能運行此代碼。

package coza.modh.fxplatform.examples.bytearray; 

import javax.swing.*; 
import java.sql.Connection; 
import java.sql.DriverManager; 
import java.sql.ResultSet; 
import java.sql.Statement; 

/** 
* Created by Willie van Zyl on 2014/07/04. 
*/ 
public class ByteArray { 

    public static void main(String[] args) { 
     ByteArray byteArray = new ByteArray(); 
     byteArray.createByteArray(); 
    } 

    private void createByteArray() { 

     String object = "This is a string object"; 
     byte[] bArray = null; 

     System.out.println(object); 

     try { 
      java.io.ByteArrayOutputStream baos = new java.io.ByteArrayOutputStream(); 
      java.io.ObjectOutputStream objOstream = new java.io.ObjectOutputStream(baos); 
      objOstream.writeObject(object); 
      bArray = baos.toByteArray(); 

      System.out.println(bArray + " is the byte[] representation of the string object"); 

      baos.close(); 
      objOstream.close(); 

     } catch (Exception e) { 
      System.out.println(e.getMessage()); 
     } 

     System.out.println("byte [] created successfully"); 

     if (writeToDB(bArray)) { 
      System.out.println("byte[] successfully written to database"); 
     } 
     else { 
      System.out.println("error writing byte[] to database"); 
      System.exit(-1); 
     } 

     bArray = readFromDB(); 

     java.io.ByteArrayInputStream bis = new java.io.ByteArrayInputStream(bArray); 
     java.io.ObjectInput in; 

     try { 
      in = new java.io.ObjectInputStream(bis); 
      object = in.readObject().toString(); 
      System.out.println(object); 

     } catch (Exception e) { 
      System.out.println(e.getMessage()); 
     } 

     System.out.println("string successfully created"); 
    } 

    private boolean writeToDB(byte[] object) { 

     boolean result = false; 

     try { 
      String dbUrl = "C:\\Users\\User\\db\\test"; 
      String input = JOptionPane.showInputDialog(null, "DB String: (" + dbUrl +")"); 

      if (!input.equals("")) dbUrl = "jdbc:h2:" + input; else dbUrl = "jdbc:h2:" + dbUrl; 
      String dbDriverClass = "org.h2.Driver"; 
      String userName = "sa"; 
      String password = "sa"; 

      Class.forName(dbDriverClass); 
      Connection connection = DriverManager.getConnection(dbUrl, userName, password); 
      Statement statement = connection.createStatement(); 

      statement.execute("drop table if exists TEST"); 
      statement.execute("create table TEST(OBJECT BINARY)"); 

      statement.execute("insert into TEST (OBJECT) values ('" + object + "')"); 

      connection.close(); 
      statement.close(); 

      result = true; 

     } catch (Exception except) { 
      except.printStackTrace(); 
     } 

     return result; 
    } 

    private byte[] readFromDB() { 

     byte[] bArray = null; 

     try { 
      String dbUrl = "C:\\Users\\User\\db\\test"; 
      String input = JOptionPane.showInputDialog(null, "DB String: (" + dbUrl +")"); 

      if (!input.equals("")) dbUrl = "jdbc:h2:" + input; else dbUrl = "jdbc:h2:" + dbUrl; 
      String dbDriverClass = "org.h2.Driver"; 
      String userName = "sa"; 
      String password = "sa"; 

      Class.forName(dbDriverClass); 
      Connection connection = DriverManager.getConnection(dbUrl, userName, password); 
      Statement statement = connection.createStatement(); 

      ResultSet results = statement.executeQuery("select * from TEST"); 

      while (results.next()) { 
       bArray = results.getBytes("OBJECT"); 
      } 

      connection.close(); 
      statement.close(); 

     } catch (Exception except) { 
      except.printStackTrace(); 
     } 

     return bArray; 
    } 


} 

這是輸出我得到:

This is a string object 

[[email protected] is the byte[] representation of the string object 

byte [] created successfully 

org.h2.jdbc.JdbcSQLException: Hexadecimal string contains non-hex character: "[[email protected]"; SQL statement: insert into TEST (OBJECT) values ('[[email protected]') -- ('[[email protected]') [90004-178] at org.h2.message.DbException.getJdbcSQLException(DbException.java:344)  at org.h2.message.DbException.get(DbException.java:178)  at org.h2.message.DbException.get(DbException.java:154)  at org.h2.util.StringUtils.convertHexToBytes(StringUtils.java:966) at org.h2.value.Value.convertTo(Value.java:864)  at org.h2.table.Column.convert(Column.java:151)  at org.h2.command.dml.Insert.insertRows(Insert.java:144) at org.h2.command.dml.Insert.update(Insert.java:115) at org.h2.command.CommandContainer.update(CommandContainer.java:79)  at org.h2.command.Command.executeUpdate(Command.java:254) at org.h2.jdbc.JdbcStatement.executeInternal(JdbcStatement.java:186) at org.h2.jdbc.JdbcStatement.execute(JdbcStatement.java:160) at coza.modh.fxplatform.examples.bytearray.ByteArray.writeToDB(ByteArray.java:88) at coza.modh.fxplatform.examples.bytearray.ByteArray.createByteArray(ByteArray.java:43)  at coza.modh.fxplatform.examples.bytearray.ByteArray.main(ByteArray.java:16) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at >sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:483)  at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134) 

錯誤是[B @ 11210ee不包含非十六進制字符完全正確。 [B @特別看起來不正確。我只是覺得我沒有很好的處理byte []的工作方式。任何幫助,將不勝感激。

+0

'[B @ 11210ee'是byte []對象的字符串表示形式。 –

回答

3

最好的方法是使用事先準備好的聲明:

byte[] object = ...; 
PreparedStatement prep = conn.prepareStatement(
    "insert into TEST (OBJECT) values (?)"); 
prep.setBytes(1, object); 

另一種方法是將字節數組轉換爲十六進制值,但是這更復雜。

+0

所以我只是寫對象的內存地址到數據庫?我也這麼想。我完全誤解了這句話:'映射到字節[]' – wmdvanzyl

+0

如果我沒有編輯數據如何寫入數據庫(這是一個例子),我不得不將字節[]轉換爲十六進制值? 第一個解決方案提供[這裏](http://stackoverflow.com/questions/2817752/java-code-to-convert-byte-to-hexadecimal)工作?如果將byte []轉換爲StringBuilder對象,那麼數據庫列類型必須是什麼? – wmdvanzyl

+2

在這種情況下,您應該將'insert into TEST(OBJECT)values(X'ab010c')'寫入[記錄](http://h2database.com/html/grammar.html#bytes)。請注意字節之間沒有空格。 –

相關問題