【YashanDB知识库】YashanDB的JDBC/OCI驱动如何设置字符编码
问题现象
Oracle、Mysql数据库链接串,JDBC驱动连接串可以指定客户端的编码格式:
jdbc:mysql://hostname:port/database_name?useUnicode=true&characterEncoding=utf8mb4
jdbc:oracle:thin:@//hostname:port/service_name?NLS_LANGUAGE=AMERICAN&NLS_TERRITORY=AMERICA&NLS_CHARACTERSET=UTF8
YashanDB JDBC连接串没有对应的参数:连接数据库 | YashanDB Doc

经常收到客户的反馈,YashanDB JDBC没有对应的字符编码参数设置,客户端和服务端编码不一致,要怎么处理?同样的OCI接口是否有对应的字符编码参数可以设置?
问题的风险及影响
YashanDB已解决,无风险。
问题影响的版本
YashanDB JDBC/OCI驱动所有版本
问题发生原因
使用问题,详见问题分析和处理过程。
解决方法及规避方式
非问题,无须规避
问题分析和处理过程
了解字符编码
通常我们会遇到UTF-8、GBK,为了解背后的机制,还需要了解字符集、编码的一些知识:
字符集:抽象二进制和字符间的对应关系,这套对应关系不考虑具体实现,只确定映射本身。GBK就是一套字符集。
编码:计算机二进制和字符间的对应关系的实际编码实现,这套映射体现在计算机实际存储字符串的二进制序列上。UTF-8就是一种编码的方式。
ASCII 码:一共规定了128个字符的编码,最前面的一位统一规定为0
Unicode:国际标准字符集,现在的规模可以容纳100多万个符号。每个符号的编码都不一样。
UTF-8:Unicode Transformation Format,互联网上使用最广的Unicode的一种实现,对英文使用8位(即一个字节),中文使用24位(三个字节)来编码,另外还有UTF-16、Oracle常见的AL32UTF8等
GBK: 严格来说是汉字字符集定义,也可以看做字符编码方式,因为它定义汉字字符集的同时也规定了如何将这些字符编码转换为二进制字节序列。有下面多种,GB2312使用2个字节来编码。

GBK、GB2312等与UTF8之间通过Unicode编码能相互转换:
GBK、GB2312 --先转--> Unicode --再转--> UTF8
UTF8 --先转--> Unicode --再转--> GBK、GB2312
相应的资料比较多,可以参考这篇:字符编码那点事:快速理解ASCII、Unicode、GBK和UTF-8 - 知乎 (zhihu.com)
YashanDB JDBC自动转码
JAVA的StringCoding提供了字符转换工具,YashanDB JDBC驱动利用了该工具实现了自动编解码:
首先驱动会读取JVM的编码设置,假如服务端字符集与JVM字符集不同,则:
把数据从客户端传到服务端时,JDBC自动按照服务端设置的字符集进行转换。
从服务端传数据到客户端时,JDBC按照客户端设置的字符集进行编码。
/**
* Encodes this {@code String} into a sequence of bytes using the given
* {@linkplain java.nio.charset.Charset charset}, storing the result into a
* new byte array.
*
* <p> This method always replaces malformed-input and unmappable-character
* sequences with this charset's default replacement byte array. The
* {@link java.nio.charset.CharsetEncoder} class should be used when more
* control over the encoding process is required.
*
* @param charset
* The {@linkplain java.nio.charset.Charset} to be used to encode
* the {@code String}
*
* @return The resultant byte array
*
* @since 1.6
*/
public byte[] getBytes(Charset charset) {
if (charset == null) throw new NullPointerException();
return StringCoding.encode(charset, value, 0, value.length);
}
所以无论在什么情况下都不会出现乱码问题,用户不需要去关心JDBC字符集,也不需要设置字符集。
YashanDB OCI指定客户端编码
OCI需要指定客户端的字符集,相关的语句:
errcode = OCIEnvNlsCreate((OCIEnv**)&envhpSessionRelease, (ub4)OCI_THREADED, (dvoid*)0,
(dvoid * (*)(dvoid*, size_t))0, (dvoid * (*)(dvoid*, dvoid*, size_t))0,
(void (*)(dvoid*, dvoid*))0, (size_t)0, (dvoid**)0, 852, 0);
目前崖山只支持852和871:
#define YCI_UTF8ID 871
#define YCI_ZHS16GBK 852
例如要指定编码格式为GBK,就把852通过该接口传进去,崖山的OCI接口就可以通过852来识别出是要支持 ZHS16GBK,具体支持的值对应的字符集参考:oracle Nls_Charset_Id 字符集编码表_1507对应的字符集编码-CSDN博客
经验总结
1、JDBC不需要指定编码格式,会自动编解码。
2、OCI需要通过接口OCIEnvNlsCreate指定编码格式,目前只支持2种编码。
【YashanDB知识库】YashanDB的JDBC/OCI驱动如何设置字符编码的更多相关文章
- Oracle JDBC:驱动版本区别与区分 [转]
classes12.jar,ojdbc14.jar,ojdbc5.jar和ojdbc6.jar的区别,之间的差异 在使用Oracle JDBC驱动时,有些问题你是不是通过替换不同版本的Oracle ...
- JDBC 常用驱动类及url格式
1. oracle <dependency> <groupId>com.oracle</groupId> <artifactId>ojdbc6</ ...
- JDBC注册驱动的三种方式
JDBC注册驱动的三种方式 1.通过导入的JDBC的驱动包拿到的com.mysql.jdbc.Driver对象,利用java.sql.DriverManager对象的DriverManager.reg ...
- Qt编译Oracle OCI驱动
最近使用qt开发了一个访问数据库的工具, 默认使用ODBC驱动注入的方式,后来发现Oracle中ODBC驱动注入经常失败. 后来就想直接使用OCI方式访问,而默认情况下Qt只有Sqlite和ODBC驱 ...
- Qt5.5.1和Qt5.3.2编译OCI驱动教程及验证方法
我们都知道oracle数据库的强大,并且好多企业或者教学用到数据库时都会推荐使用.但是Qt因为版权问题没有封装oracle数据库专用驱动,网上也有一大堆说法和教程,但是或多或少的都有问题.下面废话不多 ...
- Java笔记4:JDBC纯驱动方式连接Oracle
JDBC纯驱动方式连接Oracle 1 下载Oracle提供的驱动程序包 下载地址: http://www.oracle.com/technetwork/database/enterprise-edi ...
- [转]JDBC如何进行超时设置
文档来源:https://jingyan.baidu.com/article/fc07f98922615a12ffe519ce.html 恰当的JDBC超时设置能够有效地减少服务失效的时间.本文将对数 ...
- JDBC超时原理与设置
抄录自网上,因为担心以后找不到,因此抄录之.感谢分享的大神! 英文原版:http://www.cubrid.org/blog/dev-platform/understanding-jdbc-inter ...
- jmeter—JDBC request动态参数设置
jmeter—JDBC request动态参数设置 重要参数说明: Variable Name:数据库连接池的名字,需要与JDBC Connection Configuration的Variable ...
- LCD驱动分析(一)字符设备驱动框架分析
参考:S3C2440 LCD驱动(FrameBuffer)实例开发<一> S3C2440 LCD驱动(FrameBuffer)实例开发<二> LCD驱动也是字符设备驱动,也 ...
随机推荐
- DarkHole_1靶机渗透流程
VulnHub_DarkHole1靶机渗透流程 注意:部署时,靶机的网络连接模式必须和kali一致,让靶机跟kali处于同一网段,这用kali才能扫出靶机的主机 1. 信息收集 1.1 探测IP 使用 ...
- c 语言学习第四天
if 语句 格式: // 1 // 其他语句... if(表达式){ // 其他语句... } // 其他语句... // 2 if(表达式){ }else{ } // 3 if(表达式1){ }el ...
- [oeasy]python021_赛博宝剑铭文大赏_宝剑上的铭文_特殊符号和宝物
继续运行 回忆上次内容 上次修改了 程序 将 石中剑 变成了 红色 爱之大剑 添加图片注释,不超过 140 字(可选) 可以 让宝剑 具有 更多 铭文符号 和 颜色 吗? 铭文 亚 ...
- Sysbench 使用总结
Sysbench使用总结 实践环境 CentOS 7.8 Sysbench 1.0.20 下载地址:https://github.com/akopytov/sysbench/archive/refs/ ...
- 【SQL】Lag/Rank/Over窗口函数揭秘,数据分析之旅
七月的夏日,阳光如火,但小悦的心中却是一片清凉与激情.在数据分析项目组的新岗位上,她仿佛找到了自己新的舞台,这里让她得以将深厚的后端技术实力与数据分析的精髓深度融合.每天,她都沉浸在业务需求的分析与数 ...
- 支付宝小程序的级联选择器,对接简单操作,Cascader 级联选择器element_ui
首先,对于element_ui 的动接,由于需要数据格式是 但是支付宝提的接口返回的数据是另一种格式,并且支付宝的三级联动接口是先只有一个列表,点击列表项再发现请求,生成另外一个下拉选择, 需要这个三 ...
- XXL-JOB分片执行分布式任务
XXL-JOB相对于springtask来说优点之一就是分布式执行任务,可以在调度中心为执行器分发任务,实现分布式. 分片广播任务即当一个微服务形成集群的时候,任务会完整的下发给每一个执行器.而不像其 ...
- mybatisplus实现一次多表联查+分页查询
众所周知,mybatisplus非常好用,但是他不好用就不好用在不可以多表联查.在mybatisplusjoin中提供了联查的方法,那个参数我没看懂Orz 不过,历经千辛万苦,我通过xml终于写出来了 ...
- docker 部署redis 并在外部访问 docker命令
docker search redis //搜索redis版本 docker pull redis //拉取最新版本 docker run -d --name redis -p 自定义端口:6379 ...
- hadoop 查看日志
告警和日志信息监控 hadoop集群启动 su - hadoop #切换到hadoop用户 [hadoop@master ~]$ start-all.sh #启动 zookeeper集群启动 zkSe ...