轉載:http://blog.csdn.net/a19881029/article/details/7902701
問題描述:
向Oracle數據庫中一varchar2(64)類型字段中插入一條String類型數據,程序使用String.length()來進行數據的長度校 驗,如果數據是純英文,沒有問題,但是如果數據中包含中文,校驗可以通過,但是在數據入庫時經常會報數據超長。
問題分析:
既然問題是數據超長,那么問題應該就是出在數據長度校驗上,也就是出在String.length()這個方法上,來看看JDK是如何描述這個方法的:
- length
- public int length()返回此字符串的長度。長度等於字符串中 Unicode 代碼單元的數量。
- 指定者:
- 接口 CharSequence 中的 length
- 返回:
- 此對象表示的字符序列的長度。
- public static void main(String[] args) throws UnsupportedEncodingException {
- String a = "123abc";
- System.out.println(a.length());
- a = "中文";
- System.out.println(a.length());
- }
結果為6和2。這個方法判斷的是String串的字符長度,但是Oracle數據庫中卻是以字節來判斷varchar2類型數據長度(如: 字段定義為varchar2(64),則存入該字段的字符串的字節長度不得超過64)。如果String串為純英文,那么一個英文字母是一個字符,長度為 1,占1個字節,不會出錯,但如果String串中包含中文,一個中文漢字也是一個字符,長度為1,但是卻占多個字節(具體占幾個字節跟使用的編碼有 關),如果數據中包含中文,數據的長度就很有可能會超過數據庫中對應字段的長度限制
不同數據庫對字符串類型數據長度的計算方式不同,如:mysql數據庫中以字符長度來判斷varchar類型數據的長度(如:字段定義varchar,長度定為64,小數位定義為0,則存入該字段的字符串的字符長度不得超過64)
解決方式:
既然是判斷數據長度時以字符為標准導致出錯,那么思路就很明確了,在進行數據長度校驗時,取數據的字節長度:
- public static void main(String[] args) throws UnsupportedEncodingException {
- String a = "123abc";
- int num = a.getBytes("utf-8").length;
- System.out.println(num);
- a = "中文";
- num = a.getBytes("utf-8").length;
- System.out.println(num);
- }
結果為6和6,為什么轉換成utf-8呢,因為數據庫使用的是utf-8編碼,既然數據最終是要存到數據庫中,那么首先先要保證數據在程序中時、在 數據庫中時的編碼一致(同一個字符在不同的編碼格式中所占的字節位數不一致,這點很關鍵),然后再保證程序和數據庫判斷數據長度的方式一致,才能避免程序 校驗通過,入庫時卻提示數據長度超長的問題。