common-jdbc说明

oracle使用西文数据库时,使用jdbc直接访问得到的是乱码,需要手工转码,虽然oraclejdbc的文档表明似乎oci方式是
完全等同于客户端方式,只要客户端nls设置正确就可以正常存取,但是鄙人折腾一天都没搞定。另外实验发现,此种西文
数据库情况,如果不转码,在jsp页面输出的话,由浏览器负责转码也可以保证输入输出正常,但是中间部分就没法做单元
测试和一些值修改操作了。而且在我使用的wicket框架里面也无法这样设置转换。

最后还是绝定通过修补jdbc的方式来实现自动转码,最初想法是反编译oracle的jdbc, 对setString, getString, sql,进行转码修补,但是发现反编译后的代码有问题,修复工作量太大。再考虑这种方式会导致不容易升级jdbc,遂想用proxy的方式来实现一套jdbc壳,起初考虑省时间用p6spy的修改,后来搜索发现网络强人[http://www.dling.com] 令少已经干了同样的事情了,就直接拿过来改了。

他主要是改了2个地方,一个是getString做了中文转码,而setString没转码,只做了trim处理(trim的原因是oracle的char的问题。 和通常的理解不同的是, char类型并不比varchar2更有效率。 在现在版本的oracle中,char实际是一种伪装的varchar2. 保留char可能是为了和以前版本兼容。而char本身在使用上有很多问题,主要是他会自动补齐字符串,导致比对时候容易犯错。所以建议9i以后的数据库今可能使用varchar2代替char),但是我实验有点问题。

相对令少的修改:
 1. 对rs.getObject方法也进行了判断,是String对象就转码。另外还修补了几个update方法。
 2. 修补了stamment 和pstatemnt 的setString和 setObject,进行了转码
 3. 对所有会调用sql的地方进行了转码,防止sql中含有中文的情况。

基本转码方式是 取数据时 从系统字符集(8859-1)转换到gbk, 存的时候反之。

配置参看单元测试程序代码。

 

@Before
 
public void setUp() throws Exception {
  DriverManager.registerDriver(
new com.dingl.jdbc.CommonDriver());

   conn 
= DriverManager.getConnection(
  
"jdbc:common/dbtype=oracle&host=localhost&port=1521&dbname=ora9i&useTrim=yes&charset=gbk&os-charset=iso8859-1""system""manager1");
 }



可怜某公司CTO居然看不懂proxy模式,硬是冤枉俺说俺写的jdbc 不如oracle自己带的,拖慢了系统速度,该牛人居然测试出有10倍的速度差异,可怜丫。

东西在这,有用的可以拿去,反正是取之于民用之于民。

/Files/ghostdog/common-jdbc-proxy.zip