5

私はPostgreSQLをデータベースとして使用し、Javaサーブレットを使用してPostgreSQLと通信しています。私のアプリケーションでは、一致する入力ファイルのデータベースからデータをフェッチする必要があります。すべてのファイルは、データベースのbytea列に保存されます。これは私のコードです:

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[]です。そこで、ここでは、アップロードされた証明書がデータベースにすでに存在するかどうかを確認しています。それが存在する場合、私は例外をスローしています。

ただし、問題は、同じ証明書を複数回アップロードすることではなく、2つの証明書が異なるかのように例外が機能することです。

バイト値を正しく比較していますか?これを修正するにはどうすればよいですか?
編集
証明書列を主キーとして設定してみました。ただし、それでも証明書はデータベースに挿入されます。これはどのように起こりますか?内部比較も何らかの理由で失敗します。
編集
私はファイルを取得して文字列に変換しようとしました:

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はbyte[]の入力証明書です。私が得る出力は次のとおりです。

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----------------[B@17f8b39


間違った検索方法です。[B@17f8b39記憶の場所かそのようなもののように見えるからです。
回答
@jarnbjoが言ったように1つのことを覚えておく必要があります。postgressqlでバイト配列を使用する場合は常に、.Elseのみretieving or insertingを使用するかどうかに関係setBytes()なく、byte []のメモリ位置(Javaのハッシュコード)のみが挿入されます。

4

3 に答える 3

1

PreparedStatementを使用します。

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

もちろん、データを挿入するときにも同じことを行う必要があります。

于 2012-05-07T12:05:38.170 に答える
1

明らかに、表示されている結果に基づいて正しく比較を行っていません。どこで問題が発生しているのかを把握するには、デバッグを行う必要があります。次のような簡単なテストをお勧めします。

  • クリーンなデータベースから始める
  • クライアントから証明書を取得する
  • データベースに挿入します
  • すぐにもう一度読み直してください(これが唯一のデータである必要があります)-挿入したデータと読み戻したデータを比較します。それらは同じである必要があります。それらが同じでない場合は、理由を理解してください
  • それが機能したら、テストケースを拡張して、質問のようなクエリを実行します。それがゼロレコードを返す場合は、その理由を理解してください。

違いがある理由を理解するという点では、単純なバイト配列(1バイトで構成される配列など)を挿入する単純なテストケースから始めると役立つ場合があります。

于 2012-05-07T12:12:05.760 に答える
1

ファイルのチェックサムを生成してdbに保存し、ファイルのバイトではなくチェックサムに基づいてファイルの内容を確認することをお勧めします

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) + "';";

編集:

バイトをdbに挿入するときは、次を使用する必要があります。

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();
于 2012-05-07T13:16:08.057 に答える