<%@ page contentType="text/html; charset=gb2312"%> Java数据库字符国际化
网站公告:   ◆北天JAVA技术网热情为java爱好者服务,本网内容包括JAVA(JSP、servlet、EJB、webservice、j2ee、javabean、应用服务器、JavaScript),数据库(MYSQL、SQL Server、Sybase、Oracle、DB2、数据库综合知识),设计研究(设计模式、Struts、Spring、Hibernate、设计框架、设计综合知识),WEB2.0新技术(主要介绍AJAX),以及各种技术的入门、实例、例子等等,欢迎各位多来坐坐!◆  诚邀各位JAVA爱好者加盟!◆  本网站内容丰富,更新快,保证每周20篇以上!  
加入收藏
设为首页
联系站长
承接项目
  相关资源:网站首页 | 免费培训学院 | 技术论坛 | JAVA聊天室 | 作家专栏 | 开发工具 | 认证考试 | 会员俱乐部
  JAVA技术初学者园地 | jsp与servlet | javascript | Java源代码 | EJB | web service | 应用服务器 | JAVA综合知识
  设计研究设计模式 | 设计框架 | Struts | Spring | Hibernate | 开源项目 | 面向对象设计 | 设计综合知识
  数 据 库MYSQL | SQL Server | Sybase | Oracle | DB2 | Informix | Access | 数据库综合知识
  其他资源:AJAX新技术 | 网站开发 | ERP软件 | OA办公软件 | 商业智能BI | 开发综合知识 | 承接项目 | 项目试用

 
 
Java数据库字符国际化
     发布者: 发布时间:2006-07-25
数据库字符国际化是大家提问最多的问题,例如MySQL数据库大家可能在JDBC-URL添加useUnicode=true&CharacterEncoding=GBK作为中文支持的基本条件。但这有时破坏了数据的完整性,如果某些人粗心大意,就会导致数据编码错误,产生乱码。因此,我们需要一些手段在程序内部进行编码处理。人们一般通过在应用上使用 String(bytes:byte[], enc:String)/String.getBytes(enc:String)进行字符串编解码,这样做虽然易懂,但是如果遇到大字段表格,手动编码时费时费力。

我的方法:通过研究JDK类库,可以感觉到多层处理机制在数据处理上的优越性。我们完全有可能在数据库上建立一个中间层用于字符的国际化处理,我就是这么做的。仔细研究一下JDBC操作数据库出现字符编码问题的根源,很容易发现多数情况是ResultSet的几个String方法在作怪,因此我们就完全可以编写一个ResultSet中间层进行国际化处理,源码如下:


public class I18nResultSet implements ResultSet{ private String encoding; private ResultSet rs; public I18nResultSet(ResultSet rs, String encoding) throws java.io.UnsupportedEncodingException{ //检查该编码名称是否被系统支持。 "".getBytes(encoding); this.rs = rs; this.encoding = encoding; } … … //以下几个方法是进行String字符串的重编码. public String getString(int index) throws SQLException{ String data = null; try{ data = new String(rs.getBytes(index), encoding); }catch(java.io.UnsupportedEncodingException uee){} } public String getString(Stirng field) throws SQLException{ String data = null; try{ data = new String(rs.getBytes(field), encoding); }catch(java.io.UnsupportedEncodingException uee){} } public void updateString(int index, String value) throws SQLException{ try{ rs.updateBytes(index, value.getBytes(encoding)); }catch(java.io.UnsupportedEncodingException uee){} } public void updateString(String field, String value) throws SQLException{ try{ rs.updateBytes(field, value.getBytes(encoding)); }catch(java.io.UnsupportedEncodingException uee){} } … …}


可以看出, 所有的String操作都使用特定编码的字节数组进行存取,这样通过定义encoding的值实现数据库存取数据编码的一致性,且encoding完全可以通过在配置信息中动态定义。

同时,上面的程序又可以解决一些固有的字符串处理问题,例如控制符如\r\n导入到数据库中很有可能被解析为\\r\\n使其不能换行,通过字节数组操作,就可以解决这个问题。这样像文章固有格式就可以完整地保留下来而不需要进行额外转换操作。

结论,通过多层处理机制使用中间层对数据库数据进行层层处理可使处理环节之间形成松耦合关系,从而可以进行有效的控制。

下面给一个使用动态代理进行字符控制的代码(原创):

package com.yipsilon.crocodile.database;import java.sql.ResultSet;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.io.UnsupportedEncodingException;/** * 作者 yipsilon * 如要转载, 请通知作者 */public class I18nResultSetHandler implements InvocationHandler{ private ResultSet rs; private String encoding; public I18nResultSetHandler(ResultSet rs, String encoding) throws UnsupportedEncodingException{ this.rs = rs; "".getBytes(encoding); this.encoding = encoding; } public Object invoke(Object proxy, Method method, Object[] args) throws Throwable{ String methodName = method.getName(); if(methodName.equals("getString")){ Object obj = args[0]; if(obj instanceof Integer){ return decodeString(rs.getBytes(((Integer)obj).intValue()), encoding); }else{ return decodeString(rs.getBytes((String)obj), encoding); } }else if(methodName.equals("updateString")){ Object obj = args[0]; if(obj instanceof Integer){ rs.updateBytes(((Integer)obj).intValue(), encodeString((String)args[1], encoding)); }else{ rs.updateBytes((String)obj, encodeString((String)args[1], encoding)); } return null; } return method.invoke(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 str.getBytes(enc); } catch(UnsupportedEncodingException uee){ return str.getBytes(); } }}


使用时调用:

ResultSet rs = ... ; //原始的ResultSet结果集String encoding = "GBK"; //字符编码(ResultSet)Proxy.newProxyInstance(rs.getClass().getClassLoader(), rs.getClass().getInterfaces(), new I18nResultSetHandler(rs, encoding));
(转载文章请保留出处:北天JAVA技术网(www.java114.com))
 
更多精彩文章:
Java更新XML的四种常用方法简介
web.xml和struts-config.xml的配置
用JDom轻松整合Java和XML
Tomcat和MySQL的一个Server.xml
XML配置文件的读取处理
用Java生成XML
 
        
标 题:   
内 容:   
 
                                  
 
免责声明:该文章由网友发表,如果对您造成侵权,请联系站长

首页 - 承接项目 - 网站地图 - 联系我们 -
版权所有北天JAVA技术工作室 ICP证号:粤ICP备06079815号