本文介紹了如何使用Blob對象。
Java的MySQL各版本驅動(包括5.1.x和8.0.x),在實現PreparedStatement.setBlob方法時都有一些缺陷(無論連接的是mysql server還是PolarDB-X,都存在缺陷),對于一些用于存儲二進制格式(例如圖片、視頻等)的Blob對象,會有概率性的報出語法錯誤,本文列出一些需要注意的地方。
場景一:PolarDB-X版本<5.4.9
對于低版本的PolarDB-X,其自身不支持SQL中直接攜帶與連接串字符集不符的二進制信息,需要在客戶端轉義成如下列所示的十六進制字符串。
insert into t1 values (0xaabbccdd,x'aabbccdd');
方法1:對于Java用戶,可以使用PreparedStatement.setBytes方法替換setBlob方法,MySQL驅動會將byte[]轉義成十六進制字符串。
方法2:對于Java用戶,如果不方便使用方法1(例如使用Hibernate等框架,無法控制框架使用哪個set方法),請聯系阿里云技術支持,我們會提供一個定制的MySQL驅動包,該驅動包內會完成轉義。
方法3:對于其他語言用戶,請在應用程序中自行完成轉義。
場景二:5.4.9<=PolarDB-X版本<5.4.13
該版本的PolarDB-X,額外支持了_binary前綴。因此,除了場景一中的方法繼續適用之外,還有以下方法可以使用:
方法4:對于Java用戶,可以修改SQL語句,例如原語句:
insert into t1 values (?)
修改為:
insert into t1 values (_binary?)
方法5:對于Java用戶,可以使用8.0.26版本的MySQL驅動,該驅動在setBlob方法內會自動加上_binary前綴。
場景三:PolarDB-X版本>=5.4.13
該版本比較徹底的兼容了MySQL對于二進制信息的處理,上述場景一和場景二的方法繼續適用,還有以下方法可以使用:
方法6:使用utf8/utf8mb4連接數據庫,例如對于Java用戶,jdbcurl中加入參數:
useUnicode=true&characterEncoding=utf8
對于其他語言用戶,可以在建完連接后,執行:
set names utf8mb4;
實際上,MySQL驅動對于setBlob的實現是有問題的,即使是使用官方mysql server,也必須在連接使用utf8/utf8mb4編碼的情況下,才能很好的支持setBlob這種使用方法;對于gbk等編碼,都有一定的概率報語法錯誤。