熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Java編程 >> Java核心技術 >> 正文

Java數據庫字符國際化

2013-11-23 18:58:55  來源: Java核心技術 

  數據庫字符國際化是大家提問最多的問題例如MySQL數據庫大家可能在JDBCURL添加useUnicode=true&CharacterEncoding=GBK作為中文支持的基本條件但這有時破壞了數據的完整性如果某些人粗心大意就會導致數據編碼錯誤產生亂碼因此我們需要一些手段在程序內部進行編碼處理人們一般通過在應用上使用 String(bytes:byte[] enc:String)/StringgetBytes(enc:String)進行字符串編解碼這樣做雖然易懂但是如果遇到大字段表格手動編碼時費時費力
  
  我的方法通過研究JDK類庫可以感覺到多層處理機制在數據處理上的優越性我們完全有可能在數據庫上建立一個中間層用於字符的國際化處理我就是這麼做的仔細研究一下JDBC操作數據庫出現字符編碼問題的根源很容易發現多數情況是ResultSet的幾個String方法在作怪因此我們就完全可以編寫一個ResultSet中間層進行國際化處理源碼如下
  
  public class InResultSet implements ResultSet{ private String encoding; private ResultSet rs; public InResultSet(ResultSet rs String encoding) throws javaioUnsupportedEncodingException{ //檢查該編碼名稱是否被系統支持 getBytes(encoding); thisrs = rs; thisencoding = encoding; } … … //以下幾個方法是進行String字符串的重編碼 public String getString(int index) throws SQLException{ String data = null; try{ data = new String(rsgetBytes(index) encoding); }catch(javaioUnsupportedEncodingException uee){} } public String getString(Stirng field) throws SQLException{ String data = null; try{ data = new String(rsgetBytes(field) encoding); }catch(javaioUnsupportedEncodingException uee){} } public void updateString(int index String value) throws SQLException{ try{ rsupdateBytes(index valuegetBytes(encoding)); }catch(javaioUnsupportedEncodingException uee){} } public void updateString(String field String value) throws SQLException{ try{ rsupdateBytes(field valuegetBytes(encoding)); }catch(javaioUnsupportedEncodingException uee){} } … …}
  
  
  可以看出 所有的String操作都使用特定編碼的字節數組進行存取這樣通過定義encoding的值實現數據庫存取數據編碼的一致性且encoding完全可以通過在配置信息中動態定義
  
  同時上面的程序又可以解決一些固有的字符串處理問題例如控制符如\r\n導入到數據庫中很有可能被解析為\\r\\n使其不能換行通過字節數組操作就可以解決這個問題這樣像文章固有格式就可以完整地保留下來而不需要進行額外轉換操作
  
  結論通過多層處理機制使用中間層對數據庫數據進行層層處理可使處理環節之間形成松耦合關系從而可以進行有效的控制
  
  下面給一個使用動態代理進行字符控制的代碼(原創):
  
  package comyipsiloncrocodiledatabase;import javasqlResultSet;import javalangreflectInvocationHandler;import javalangreflectMethod;import javaioUnsupportedEncodingException;/** * 作者 yipsilon * 如要轉載 請通知作者 */public class InResultSetHandler implements InvocationHandler{ private ResultSet rs; private String encoding; public InResultSetHandler(ResultSet rs String encoding) throws UnsupportedEncodingException{ thisrs = rs; getBytes(encoding); thisencoding = encoding; } public Object invoke(Object proxy Method method Object[] args) throws Throwable{ String methodName = methodgetName(); if(methodNameequals(getString)){ Object obj = args[]; if(obj instanceof Integer){ return decodeString(rsgetBytes(((Integer)obj)intValue()) encoding); }else{ return decodeString(rsgetBytes((String)obj) encoding); } }else if(methodNameequals(updateString)){ Object obj = args[]; if(obj instanceof Integer){ rsupdateBytes(((Integer)obj)intValue() encodeString((String)args[] encoding)); }else{ rsupdateBytes((String)obj encodeString((String)args[] encoding)); } return null; } return methodinvoke(rs args); } private String decodeString(byte[] bytes String enc){ try{ return new String(bytes enc); } catch(UnsupportedEncodingException uee){ return new String(bytes); } } private byte[] encodeString(String str String enc){ try{ return strgetBytes(enc); } catch(UnsupportedEncodingException uee){ return strgetBytes(); } }}
  
  
  使用時調用:
  
  ResultSet rs = ; //原始的ResultSet結果集String encoding = GBK; //字符編碼(ResultSet)ProxynewProxyInstance(rsgetClass()getClassLoader() rsgetClass()getInterfaces() new InResultSetHandler(rs encoding));
  
  

From:http://tw.wingwit.com/Article/program/Java/hx/201311/26086.html
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.