使用Druid解决Oracle Thin驱动中文乱码

断了今生、忘了曾经 提交于 2019-11-30 21:44:40

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代理有@wenshaoDruid,详情可点击查看,在此不多做介绍。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> 

需要注意的是

  1. 数据库链接配置的顺序有先后要求,不能颠倒,详细要求请参看其源码,位于DruidDriver类的parseConfig方法;
  2. Druid能通过数据库链接自动识别数据库,所以无需在配置中指定(也可在“jdbc:wrap-jdbc:”后加上“driver=oracle.jdbc.driver.OracleDriver”显示指定),代码参看JdbcUtils类的getDbType方法;
  3. connectionProperties的配置最好在一行内且去除无用头尾空格,否则DataSource在解析配置时容易产生错误

4. 参考

  1. http://4ucode.com/Study/Topic/1151903
  2. http://www.blogjava.net/ghostdog/archive/2008/11/04/207058.html
  3. 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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!