1. 问题
使用Oracle Thin驱动比较麻烦的一个问题是容易出现中文乱码,且Thin驱动不像MySQL驱动那样能在链接字符串中指定编码。
2. 思路
最直接的解决方案是对所有数据库中读出的字符串进行编解码,但这么做需要编码处理所有的字符串,很麻烦。
// 编码:
String newString = new String(oldstring.getBytes(clientEncoding),serverEncoding);
// 解码:
String newString = new String(oldstring.getBytes(serverEncoding),clientEncoding);
更好的方式是使用JDBC的代理,在通过JDBC返回和写入字符串前进行编解码操作,把所有字符串的处理收拢到一起。
3. 解决
目前能可靠使用且一直有在维护和开发的JDBC代理有@wenshao的Druid,详情可点击查看,在此不多做介绍。Druid本身实现了Filter-Chain机制,能对JDBC进行灵活的扩展,并内置了一个用于进行字符编码转换的Filter。通过Druid即可很方便的解决Oracle编码问题,无需重复造轮子。
使用Druid,需要同时引入Druid和数据库驱动的依赖,Maven配置如下。
<dependencies>
……
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc14</artifactId>
<version>10.2.0.3.0</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>0.2.13</version>
</dependency>
……
</dependencies>
配置数据库数据源时(以Spring为例),则需把数据库驱动替换成Druid的,详细说明如下。
<bean id="dataSource" class="org.apache.commons.dbcp.Basic"
destroy-method="close">
<!-- Druid的JDBC代理类类名 -->
<property name="driverClassName" value="com.alibaba.druid.proxy.DruidDriver" />
<!--
数据库链接配置
“jdbc:wrap-jdbc:”,为Druid规定的JDBC Proxy链接头
“filters=encoding”,指定了字符编码转化Filter,对应的
“com.alibaba.druid.filter.encoding.EncodingConvertFilter”
“jdbc:oracle:thin:@localhost:1521:test”,为原始的Oracle数据库链接
-->
<property name="url" value="jdbc:wrap-jdbc:filters=encoding:jdbc:oracle:thin:@localhost:1521:test" />
<property name="username" value="hello" />
<property name="password" value="world" />
<property name="connectionProperties">
<!--
链接参数配置
“clientEncoding”和“serverEncoding”,分别指定数据库客户端和服务器端的字符编码
Encoding Filter从这两个参数获取编码
-->
<value>clientEncoding=GBK;serverEncoding=ISO-8859-1;</value>
</property>
</bean>
需要注意的是
- 数据库链接配置的顺序有先后要求,不能颠倒,详细要求请参看其源码,位于DruidDriver类的parseConfig方法;
- Druid能通过数据库链接自动识别数据库,所以无需在配置中指定(也可在“jdbc:wrap-jdbc:”后加上“driver=oracle.jdbc.driver.OracleDriver”显示指定),代码参看JdbcUtils类的getDbType方法;
- connectionProperties的配置最好在一行内且去除无用头尾空格,否则DataSource在解析配置时容易产生错误。
4. 参考
- http://4ucode.com/Study/Topic/1151903
- http://www.blogjava.net/ghostdog/archive/2008/11/04/207058.html
- https://github.com/alibaba/druid/wiki/%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98
5. 示例
使用Druid驱动解决DBeaver链接Oracle乱码,http://my.oschina.net/joshuazhan/blog/122591