2

我有一个很好的 MySQL 表,如下所示:

CREATE TABLE IF NOT EXISTS BLOBTest(Id INT PRIMARY KEY AUTO_INCREMENT,

    Data BLOB);

在里面我有以下内容:

SELECT HEX(Data) from BLOBTest;

+----------------------------------+
| HEX(Data)                        |
+----------------------------------+
| E764DF04463B55E9E2305934266227A1 |
+----------------------------------+

翻译后,我有一个包含 1 行和两列(Id 和 Data)的表。此行保存 byte[] 数据,存储的 byte[] 数组如下: [-25, 100, -33, 4, 70, 59, 85, -23, -30, 48, 89, 52, 38, 98 , 39, -95]

如何进行查询以获取完整的方法?起初我试过:

SELECT * FROM BLOBTest WHERE Data='[-25, 100, -33, 4, 70, 59, 85, -23, -30, 48, 89, 52, 38, 98, 39, -95]';

但是这种方法根本不起作用,它总是返回一个空集。我需要获取该行的所有信息,而我所拥有的只是 byte[] 值。我该怎么做?

如果可能的话,感谢您的帮助。

编辑:

这是java应用程序的代码及其作用。

public Map<Integer, String> queryAuthor(String author) throws Exception{

    //encrypts the name of the author
    byte[] cipheredName = cryptManager.encrypt(keyBytes, 
                author.getBytes());

    //queries db for encrypted name
    pst = con.prepareStatement("SELECT * FROM BLOBTest WHERE DATA='" + cipheredName+"'");

    //builds a map for clients to use with the information from the query. 
    ResultSet rs =  pst.executeQuery();
    Map<Integer, String> result = new HashMap<Integer, String>();
    while (rs.next()) {

        byte[] recoveredBytes = rs.getBytes(2);

        byte[] recoveredName = cryptManager.decrypt(keyBytes, 
                    recoveredBytes);

        result.put(rs.getInt(1), new String(recoveredName));

    }

    return result;
}

问题在于:

SELECT * FROM BLOBTest WHERE Data='[-25, 100, -33, 4, 70, 59, 85, -23, -30, 48, 89, 52, 38, 98, 39, -95]';

返回一个空集,从而使变量“rs”为空,因此返回的映射为空。每个人都很难过,因为我是菜鸟,无法进行这样的简单查询 =(

4

1 回答 1

5

您可以将原始字节作为字符串文字发送到 MySQL:

SELECT * FROM BLOBTest WHERE Data = '????????????????'

(由于并非所有字节都可以用可打印字符表示,我什至没有尝试过)。

如果您通过参数将数据传递给准备好的语句(无论如何您都应该这样做),这将特别容易做到:

pst = con.prepareStatement("SELECT * FROM BLOBTest WHERE DATA = ?");
pst.setBytes(1, cipheredName);

否则,您必须小心确保将 MySQL 解析为字符串终止引号的任何字节转义,否则它们会破坏您的查询。


(以下内容早于 OP 编辑​​中提供的附加信息)

如果这不可能,它可能表明您不应该将数据存储在BLOB-type 列中;例如,16TINYINT SIGNED列可能更合适。

即便如此,仍有可能:

  • 如果您可以在MariaDBMySQL中使用 Hexadecimal Literal ,它将十六进制字符串解释为其二进制形式:

      SELECT * FROM BLOBTest WHERE Data = x'E764DF04463B55E9E2305934266227A1'
    

sqlfiddle上查看。

  • UNHEX()也做了与上面十六进制文字中描述的相同的事情:

    SELECT * FROM BLOBTest WHERE Data = UNHEX('E764DF04463B55E9E2305934266227A1')
    
  • 如果您可以将每个字节转换为其无符号值:

      SELECT * FROM BLOBTest WHERE Data = CHAR(
        231,100,223,4,70,59,85,233,226,48,89,52,38,98,39,161
      )
    

sqlfiddle上查看。

  • 否则,您将需要去除最高位,因为 MySQL 将每个输入CHAR()视为 4 字节整数:

      SELECT * FROM BLOBTest WHERE Data = CHAR(
        -25 & 0xff,
        100 & 0xff,
        -33 & 0xff,
          4 & 0xff,
         70 & 0xff,
         59 & 0xff,
         85 & 0xff,
        -23 & 0xff,
        -30 & 0xff,
         48 & 0xff,
         89 & 0xff,
         52 & 0xff,
         38 & 0xff,
         98 & 0xff,
         39 & 0xff,
        -95 & 0xff
      )
    

sqlfiddle上查看。

于 2013-01-23T15:14:53.433 回答