Java 應用存取資料庫時,若資料庫要求特定編碼(如 GBK → ISO-8859-1),開發者必須在每次讀寫字串時手動轉碼,極易遺漏且程式碼冗長。本文提出在連線池與業務層之間加入「連線封裝層」,利用 Java 動態代理攔截 PreparedStatement.setString 與 ResultSet.getString,自動完成編碼/解碼,徹底消除重複轉碼代碼。
Connection。Connection、Statement、ResultSet 三層介面。_Connection 攔截 createStatement/prepareStatement,回傳被代理的 _Statement。_Statement 攔截 setString(寫入前轉碼)與 executeQuery(回傳被代理的 _ResultSet)。_ResultSet 攔截 getString(讀取後反轉碼)。// _Connection.invoke 中
if ((method.equals("prepareStatement") || method.equals("createStatement")) && coding)
return new _Statement((Statement)obj, true).getStatement();
// _Statement.invoke 中
if (decode && method.equals("setString")) {
String param = (String)args[1];
if (param != null) param = new String(param.getBytes(), "8859_1");
return method.invoke(stmt, new Object[]{args[0], param});
}
if (decode && method.equals("executeQuery")) {
ResultSet rs = (ResultSet)method.invoke(stmt, args);
return new _ResultSet(rs, decode).getResultSet();
}
// _ResultSet.invoke 中
if (decode && method.equals("getString")) {
String result = (String)method.invoke(rs, args);
if (result != null) return new String(result.getBytes("8859_1"));
return null;
}
完整原始碼(_Connection.java、_Statement.java、_ResultSet.java)已包含在內文,可直接整合至專案。