首页 > 其他分享 >【YashanDb知识库】YashanDB的JDBC/OCI驱动如何设置字符编码

【YashanDb知识库】YashanDB的JDBC/OCI驱动如何设置字符编码

时间:2024-07-25 16:55:38浏览次数:7  
标签:OCI 编码 JDBC YashanDB charset 字符集

问题现象

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种编码。

标签:OCI,编码,JDBC,YashanDB,charset,字符集
From: https://www.cnblogs.com/YashanDB/p/18323640

相关文章

  • 求教Postgresql在jdbc处理bit(1)字段的预处理解决方案
    文章目录1.建表语句:2.使用以下方式的预处理方式都报错了3.可以先用sql拼接实现功能1.建表语句:CREATETABLEpublic.h_user( idserial4notnull, usernamevarchar(50)NULL, "password"varchar(64)NULL, nicknamevarchar(60)NULL, emailvarchar(255)N......
  • 【YashanDB数据库】yasdb jdbc驱动集成druid连接池,业务(java)日志中有token IDENTIFIE
    问题现象客户的java日志中有如下异常信息:问题的风险及影响对正常的业务流程无影响,但是影响druid的mergesql功能(此功能会将sql语句中的字面量替换为绑定变量,然后将替换以后的sql视为同一个,然后用做执行性能统计)问题影响的版本与yashandb版本无关问题发生原因druid源码中在......
  • 使用python3拼接rgb.txt与depth.txt为associate.txt(适用于GCNV2_SLAM中TUM数据集的运
    这里以GCNV2_SLAM中TUM数据集的运行为例子:安装gnv2_slam可以参考:GCNv2_SLAM-CPU详细安装教程(ubuntu18.04)-CSDN博客首先下载数据集ComputerVisionGroup-DatasetDownload下载后通过该命令解压:tar-xvfrgbd_dataset_freiburg1_desk.tgz打开后,你可以发现:在该数据集......
  • 【YashanDB知识库】stmt未close,导致YAS-00103 no free block in sql main pool part 0
    问题现象问题单:YAS-00103nofreeblockinsqlmainpoolpart0,YAS-00105outofmemorytoallocatehashtableofsize=256现象:业务处理sql时,报错YAS-00103nofreeblockinsqlmainpoolpart0问题风险及影响业务处理报错,影响功能使用问题影响版本客户版本:22.2.4......
  • 【YashanDB知识库】filter or改写问题
    问题现象当filter中出现or的时候,会导致filter无法走索引或者走hashjoin,就需要进行改写,例如:createtabletest_tab1(col1int,col2int,col3int);createtabletest_tab2(col4int,col5int,col6int);beginforiin1..10000loopinsertintotest_tab1values(i......
  • Jmeter取样器--- JDBC request
    以mysql为例1、将访问mysql的jdbc的jar包放入jmeter\lib\ext目录下,如E:\JMeter\apache-jmeter-5.6.3\lib\ext,重新启动jmeter。驱动下载地址:MySQL::DownloadMySQLConnector/J(ArchivedVersions)2、添加配置元件“JDBCConnectionConfiguration”,如图所示3、JDBCConne......
  • shardingjdbc 使用记录
    注意几个概念:数据源,数据源别名(shardingjdbc的配置会给每个数据源配置别名)db实例(物理概念),逻辑库如果db实例是同一个的话,那么可以只配置一个数据源,通过shardingjdbc的路由策略来路由到具体的逻辑库。这样可以降低db的连接数。  配置了hint的路由策略,但是没有生效,断点......
  • 【YashanDB知识库】yac修改参数后关闭数据库hang住
    【标题】yac修改参数后关闭数据库hang住【问题分类】性能优化【关键词】YashanDB,yac,shutdownhang【问题描述】修改yac参数后执行shutdownimmediate,数据库hang住。【问题原因分析】Shutdown操作时,线程在获取gInstance->trigger->sema信号量时卡住。该信号量应由mai......
  • 【YashanDB知识库】EXP导致主机卡死问题
    问题现象问题单:exp导出全库1主2备主节点执行,DMP文件30G左右系统卡死,发生主备切换现象:expsys/Cod-2022file=bim20240402.dmpfull=y服务器卡死,ssh连接不上服务器。等待一两个小时后,可以重新连接上。备用节点升主正常,查看run.log,心跳发送不到主节点。重连后,yasdb不......
  • 【vue+jdbc实现数据库操作java web前后分离版】
    创建数据库droptableifexistsusers;createtableusers(idbigint(20)notnullauto_incrementcomment'用户id',usernamevarchar(100)default''comment'用户名',phone......