2012-05-07 48 views
4

比較字節值我使用PostgreSQL作爲我的數據庫和Java Servlet的與PostgreSQL打交道。我的應用程序要求我從數據庫中獲取匹配輸入文件的數據。所有文件都存儲在數據庫的bytea列中。這是我的代碼:用bytea的列在PostgreSQL中

String checkdb="select * from key where certificate = '"+c+"';"; 
Statement stcheck=conn.createStatement(
    ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE); 
ResultSet newrs=stcheck.executeQuery(checkdb); 
newrs.last(); 
int rowcount=newrs.getRow(); 
if(rowcount!=0) 
throw new ArithmeticException(); 

certificate哪裏是包含BYTEA數據的列的名稱和c(上載)是byte[]形式的證書。所以我在這裏檢查上傳的證書是否已經存在於數據庫中。如果它存在,我就拋出一個例外。

但問題是相同的證書多次上傳不拋出異常的工作,就好像兩個證書是不同的。

我是比較正確的字節值。我該怎麼做才能糾正這個問題?
EDIT
我嘗試設置證書列作爲主鍵。但仍然將證書插入到數據庫中。這怎麼會發生?由於某種原因,內部比較也失敗。
EDIT
我試圖檢索Ile和它轉換成字符串:

InputStream input13 = retrs.getBinaryStream("certificate"); 
     ByteArrayOutputStream output13 = new ByteArrayOutputStream(); 
     byte buf[]=new byte[1024]; 
      int len; 
    IOUtils.copy(input13, output13); 
    input13.close(); 
    byte[] retvalue=output13.toByteArray(); 
    String s1=new String(retvalue); 

String s2=new String(c); 
System.out.println("in--------------"+s2); 


System.out.println("out----------------"+s1); 


retrs是包含剛存儲的證書的結果集。 c是字節[]中的輸入證書。該出來把我得到的是:

19:05:43,156 INFO [STDOUT] in-------------------BEGIN CERTIFICATE----- 
MIICIjCCAYsCAQMwDQYJKoZIhvcNAQEFBQAwYTELMAkGA1UEBhMCYXMxCzAJBgNV 
BAgMAmFzMQswCQYDVQQHDAJhczELMAkGA1UECgwCYXMxCzAJBgNVBAsMAmFzMQsw 
CQYDVQQDDAJjYTERMA8GCSqGSIb3DQEJARYCYXMwHhcNMTIwNDEwMDY0ODQ3WhcN 
MTMwNDEwMDY0ODQ3WjBSMQswCQYDVQQGEwJhczELMAkGA1UECBMCYXMxCzAJBgNV 
BAcTAmFzMQswCQYDVQQKEwJhczELMAkGA1UECxMCYXMxDzANBgNVBAMTBmNsaWVu 
dDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAsfJq9TVgTLqz84nuWpDm+dvI 
do2HIWoHkmEPNowK4xn1+qWUPCy30aASWI92YMtE6njtQGyZBYij0iTAxldDktqd 
bMdpKAONDlSv71rn+fZPuyenbBFYZexybNVsRMFzTD/F/hiPPXT7E1j9CrgIMxVz 
ScZeNATh/dPLwuNQ0dsCAwEAATANBgkqhkiG9w0BAQUFAAOBgQDDUyeIWlKaMMkM 
8VRGuDJyKFC8miQfmul6zE4+6RTswHKjcUoje2vhTQgV+GBfqx8ai+ziujx8CeyR 
eJWcb1G8gg+LMUNDcTOlXTeBG9L2c/gMOEu7BEjtpojSYmFyEvJEQ5Yep44HKZZb 
FSPFVNxGiXBhNxtKQdAu6/smQ/eBNg== 
-----END CERTIFICATE----- 
19:05:43,156 INFO [STDOUT] out----------------[[email protected] 


是我的錯檢索方式。因爲[[email protected]看起來像內存位置或類似的東西。
答案
正如@jarnbjo所說有一件事必須記住。當你在postgressql中使用字節數組時,無論是使用retieving or inserting,只使用setBytes()。只有字節[]的內存位置(java中的哈希碼)被插入。

+0

什麼版本的PostgreSQL這是什麼?什麼是JDBC驅動程序的jar文件? (使用驅動程序的舊主版本可能比服務器有問題。) – kgrittn

+0

@kgrittn:我的jar版本 - postgresql-8.4-703.jdbc3.jar和我的postgresql版本8.4。 – Ashwin

回答

1

使用PreparedStatement:

PreparedStatement pstat = conn.prepareStatement(
     "select * from key where certificate = ?"); 
pstat.setBytes(1, c); 
ResultSet newrs = pstat.executeQuery(); 

插入數據,以及時,你當然應該這樣做。

+0

仍然是相同的結果。 – Ashwin

+0

明確的不是。如果是這樣,你必須在這裏沒有顯示的部分代碼中做一些其他的錯誤。 – jarnbjo

+0

我甚至嘗試將證書列設置爲主鍵。但同一個文件被插入多次。如果我在錯誤的地方postgres不應該在給出主鍵約束後再次存儲相同的文件。 – Ashwin

1

顯然,你是不是做的基礎上正確,你所看到的結果進行比較。你需要做一些調試來弄清楚哪裏出了問題。我建議大意如下簡單的測試:

  • 開始用乾淨的數據庫
  • 獲得來自客戶端的證書
  • 將其插入到數據庫
  • 立即讀回出再次(它應該是唯一的) - 將您插入的數據與您讀回的數據進行比較。他們應該是一樣的。如果它們不相同,請找出原因
  • 一旦運行,擴展測試用例以運行類似於您的問題中的查詢的查詢。如果它返回零記錄,找出原因。

在計算出爲什麼會有差異的情況下,您可能會發現從插入簡單字節數組(例如由單個字節組成的數組)的簡單測試用例開始很有幫助。

1

我會根據校驗,而不是文件的字節

table key{ 
    id int, 
    certificate blob, 
    checksum varchar(32) 
} 

,並使用以下方法生成的byte[] buffer

校驗建議您生成文件在數據庫校驗和存儲,並檢查文件內容
public String getCheckSum(byte[] buffer) { 
    StringBuilder builder = new StringBuilder(); 
    try { 
     MessageDigest complete; 
     complete = MessageDigest.getInstance("MD5"); 
     byte[] rawCheckSum = complete.digest(buffer); 
     for(byte b: rawCheckSum) { 
      builder.append(Integer.toString((b & 0xff) + 0x100, 16).substring(1)); 
     } 
    } catch (NoSuchAlgorithmException e) { 
     throw new RuntimeException(e); 
    } 
    return builder.toString(); 
} 

最後,

String checkdb="select * from key where checksum = '" + getCheckSum(c) + "';"; 

編輯:

當插入字節到數據庫,你應該使用:

String query = "INSERT INTO key (certificate) VALUES (?)"; 
PreparedStatement pstmt = connection.prepareStatement(query); 
pstmt.setBytes(1, c); 

而不是

String query = "INSERT INTO key (certificate) VALUES ('" + c + "')"; 
PreparedStatement pstmt = connection.prepareStatement(query); 
pstmt.execute(); 
+0

請參閱編輯。 – Ashwin

+0

我不認爲問題是用於檢索該文件的主鍵。問題在於檢索文件本身。請參閱編輯。 – Ashwin

+0

@Ashwin我相信你的問題是無法識別兩個相同的文件基於比較'字節'權利?然後,我建議比較文件的校驗和,而不是比較文件「字節」。 –

相關問題