全球化和日期格式
本主题主要描述 GBase 8s JDBC Driver 如何通过提高对基于不同语言环境和代码集的 GBase 8s 数据库的访问来扩展 JDK 全球化功能。
全球化使您可以独立于用户的国家或语言来开发软件,然后将软件本地化为多个国家和地区。
支持 JDK 和全球化
JDK 为开发全球性的应用程序提供了丰富的 API。这些全球化 API 基于 Unicode 2.0 代码集,可以将文本、数字、日期、货币和用户定义的对象调整为任何国家的惯例。
这些全球化 API 集中在这三个包中:
- java.text 包,包含以对语言环境敏感的方式处理文本的类和接口。
- java.io 包,包含用于导出和导入非 Unicode 字符数据的新类。
- java.util 包,包含 Locale 类、全球化支持类以及用于日期和时间处理的新类。
JDK 语言环境和 JDK 代码集之间没有联系;您必须保持这些代码集的一致性。
支持 GBase 8s GLS 变量
全球化将下表中的环境变量添加到 GBase 8s JDBC Driver。
支持的 GBase 8s 环境变量 | 描述 |
---|---|
CLIENT_LOCALE | 指定访问数据库的客户机的本地语言环境。提供例如 GL_DATE 格式这样的用户定义格式的缺省值。用户定义的数据类型可以使用它来进行代码集转换。数据库服务器使用它和 DB_LOCALE 变量一起建立服务器处理的语言环境。DB_LOCALE 和 CLIENT_LOCALE 值必须是相同的,或者它们的代码集必须是可转换的。 |
DBCENTURY | 使您为具有一位数或两位数年份的 DATE 值指定适当的扩展。 |
DBDATE | 指定 DATE 列中值的最终用户格式。支持与早期版本兼容;首选 GL_DATE 。 |
DB_LOCALE | 指定数据库的本地语言环境。GBase 8s JDBC Driver 使用此变量在Unicode 和数据库本地语句环境中指定代码集转换。数据库服务器使用它和 CLIENT_LOCALE 变量一起建立服务器处理语言环境。DB_LOCALE 和CLIENT_LOCALE 值必须是一样的,或者它们的代码集必须是可转换的。 |
GL_DATE | 指定 DATE 列中值的最终用户格式。 |
GL_USEGLU | 要使用 Unicode 国际化组件(ICU)启用 Java/JDBC 客户端应用程序进行 Unicode 的归类,请在连接到GBase 8s 实例之前,在连接字符串中指定 GL_USEGLU=1。这使服务器能够使用 Java™ 所需的高级 Unicode 转换。在启动服务器之前和创建数据库之前,数据库服务器环境中的 GL_USEGLU 环境变量值必须设置为 1。 |
NEWCODESET | 允许在 GBase 8s JDBC Driver 的发行版之间创建新的代码集。 |
NEWLOCALE | 允许在 GBase 8s JDBC Driver 的发行版之间定义新的语言环境。 |
即使有 CLIENT_LOCALE 设置可用,GBase 8s JDBC Driver 也不更改十进制格式。全球化应该在使用 DecimalFormat 类的 Java 应用程序中完成。
除非数据库服务器支持 GBase 8s GLS 特性,才支持 DB_LOCALE 、CLIENT_LOCALE 和 GL_DATE 变量。
支持 DATE 最终用户格式
最终用户格式是 DATE 值出现在字符串变量中的格式。本节描述了指定 DATE 最终用户格式的 GL_DATE 、DBDATE 和 DBCENTURY 变量。这些变量是可选的。
GBase 8s JDBC Driver 不支持 DBDATE 或 GL_DATE 环境变量的 ALS 6.0 、5.0 或 4.0 格式。
GL_DATE 变量
GL_DATE 环境变量指定 DATE 列的值的最终用户格式。 GL_DATE 格式字符串可以包含以下字符:
- 一个或多个空格字符
- 普通字符(不是百分号或空格字符)
- 格式化指令。由百分号(% )和一个或两个指定所需替换的转换字符组成
在下表中定义日期格式化伪指令。
指令 | 替换为 |
---|---|
%a | 在语言环境中定义为星期几名称的缩写 |
%A | 语言环境中定义的星期几的完整名称 |
%b | 语言环境中定义的月的缩写 |
%B | 语言环境中定义的完整的月的名称 |
%C | 作为十进制(00 到 99)的世纪数(年除以 100 并截断为整数) |
%d | 一个月份中的日期数(01 到 31) 单个数字前面要加零(0) |
%D | 与 %m/%d/%y 格式相同 |
e | 一个月份中的日期数(1 到 31) 单个数字前面用空格补齐 |
%h | 与 %b 格式指令相同 |
%iy | 两位数表示的年份(00 到 99) 这是针对于 %y 的特定于 GBase 8s 的格式化指令 |
%iY | 四位数表示的年份(0000 到 9999) 这是针对于 %Y 的特定于 GBase 8s 的格式化指令 |
%m | 月份(01 到 12) |
%n | newline 字符 |
%t | TAB 字符 |
%w | 星期数(0 - 6) 0 代表本地语言中的星期日。 |
%x | 表示语言环境定义的特殊日期 |
%y | 两位数表示的年份(00 - 99) |
%Y | 四位数表示的年份( 0000 - 9999) |
%% | % (在格式化字符串中允许 % ) |
不支持字段规范的 GL_DATE 可选日期格式限定符。
例如,通过使用 %4m 显示月份作为十进制数值,不支持最大字段宽度为 4 。
不支持 GL_DATE 转换修饰符 O,它指示使用替代数字用于替换日期格式 。
任何两个格式化指令之间必须出现空格或其它非字母数字字符。如果 GL_DATE 变量格式与任何有效的格式指令都不对应,则当数据库服务器尝试格式化日期时会发生错误。
例如,对于美国英语语言环境,您可以使用以下格式将 09/29/1998 格式化为内部 DATE 值:
* Sep 29, 1998 this day is:(Tuesday), a fine day *
要创建此格式, 将 GL_DATE 环境变量设置为如下值:
* %b %d, %Y this day is:(%A), a fine day *
要将此日期值插入到具有日期列的数据库表中,您可以执行以下类型的插入:
- 非本地化 SQL,其中 SQL 语句未更改地发送到数据库服务器
输入完全按照 GL_DATE 设置预期的日期
- 本地化 SQL,将转义语法转换为特定于 GBase 8s 格式
以 JDBC 转义格式 yyyy-mm-dd 输入日期值;该值会自动转换为 GL_DATE 格式。
以下示例显示这两种类型的插入:
要从数据库中检索格式化的 GL_DATE DATE 值,请调用 ResultSet 类的 getString() 方法。
将表示日期的字符串输入数据库表的 char 、varchar 或 lvarchar 类型列,您还可以建立表示日期字符串值的日期对象。此日期字符串值必须是GL_DATE 格式。
以下示例显示查询 DATE 值的这两种方式:
PreparedStatement pstmt = conn.prepareStatement("Select * from
tablename "
+ "where col2 like ?;");
pstmt.setString(1, "%Tue%");
ResultSet r = pstmt.executeQuery();
while(r.next())
{
String s = r.getString(1);
java.sql.Date d = r.getDate(2);
System.out.println("Select: column col1 (GL_DATE format) = <"
+ s + ">");
System.out.println("Select: column col2 (JDBC Escape format) = <"
+ d + ">");
}
r.close();
pstmt.close();
DBDATE 变量 (deprecated)
对新的应用程序使用 GL_DATE 环境变量。
DBDATE 环境变量指定 DATE 列中的值的最终用户格式。使用以下方式使用最终用户格式:
- 当输入 DATE 值时,GBase 8s 产品使用 DBDATE 环境变量解释此输入。例如,如果在 INSERT 语句中指定字符 DATE 值,则 GBase 8s数据库服务器要求此字符值与 DBDATE 变量指定的格式兼容。
- 当显示 DATE 值时,GBase 8s 产品使用 DBDATE 环境变量格式化此输出。
使用标准化格式,您可以指定以下属性
- 日期中月、日和年的顺序
- 年使用两位数(Y2)还是四位数(Y4)输出
- 月、日和年之间的分隔符
格式化字符串可以包含以下字符:
- 连字符( - )、点(.)和斜杠(/)是日期格式中的分隔符字符。分隔符出现在格式化字符串的末尾(例如 Y4MD-)。
- 0 指示不显示分隔符。
- D 和 M 是代表日和月的字符。
- Y2 和 Y4 是代表年和年的位数。
下列格式字符串是有效的标准 DBDATE 格式:
- DMY2
- DMY4
- MDY4
- MDY2
- Y4MD
- Y4DM
- Y2MD
- Y2DM
分隔符通常出现在格式化字符串的末尾(例如 DMY2/)。如果未指定分隔符或有效的字符,则缺省为斜杠字符(/)。
对于美国 ASCII 英语语言环境,DBDATE 的缺省设置为 Y4MD-,其中 Y4 代表四位数的年份,M 代表月份,D 代表日,连字符(-)是分隔符(例如 1998-10-08)。
要将日期值插入到具有日期列的数据库表,您可以执行以下插入:
- 非本地化 SQL。其中 SQL 语句未更改地发送到数据库服务器
输入完全按照 DBDATE 设置预期的日期
- 本地化 SQL。转义语法转换为特定于 GBase 8s 格式
以 JDBC 转义格式 yyyy-mm-dd 输入日期值;该值会自动转换为 DBDATE 格式。
以下示例显示这两种类型的插入(DBDATE 值是 MDY2-):
stmt = conn.createStatement();
cmd = "create table tablename (col1 date, col2 varchar(20));";
rc = stmt.executeUpdate(cmd);..
.String[] dateVals = {"'08-10-98'", "{d '1998-08-11'}" };
String[] charVals = {"'08-10-98'", "'08-11-98'" };
int numRows = dateVals.length;
for (int i = 0; i < numRows; i++)
{
cmd = "insert into tablename values(" + dateVals[i] + ", " +
charVals[i] + ")";
rc = stmt.executeUpdate(cmd);
System.out.println("Insert: column col1 (date) = " + dateVals[i]);
System.out.println("Insert: column col2 (varchar) = " + charVals[i]);
}
要从数据库检索格式化的 DBDATE DATE 值,请调用 ResultSet 类的 getString 方法。
要将代表日期的字符串插入到数据库表的 char 、varchar 或 lvarchar 类型字符列,您可以创建代表日期字符串值的数据对象。此日期字符串值应为DBDATE 格式。
以下示例显示了选择 DATE 值的两种方式:
PreparedStatement pstmt = conn.prepareStatement("Select * from tablename "
+ "where col1 = ?;");
GregorianCalendar gc = new GregorianCalendar(1998, 7, 10);
java.sql.Date dateObj = new java.sql.Date(gc.getTime().getTime());
pstmt.setDate(1, dateObj);
ResultSet r = pstmt.executeQuery();
while(r.next())
{
String s = r.getString(1);
java.sql.Date d = r.getDate(2);
System.out.println("Select: column col1 (DBDATE format) = <"
+ s + ">");
System.out.println("Select: column col2 (JDBC Escape format) = <"
+ d + ">");
}
r.close();
pstmt.close();
DBCENTURY 变量
如果 String 值代表小于三位数年份的 DATE 值并设置了 DBCENTURY ,则 GBase 8s JDBC Driver 将此 String 值转换为 DATE 值,并使用DBCENTURY 属性决定年份的正确的四位数扩展。
下表总结了受影响的方法和受影响的条件。
方法 | 条件 |
---|---|
PreparedStatement.setString(int, String) | 目标列为 DATE。 |
PreparedStatement.setObject(int, String) | 目标列为 DATE。 |
IfxPreparedStatement.IfxSetObject(String) | 目标列为 DATE。 |
ResultSet.getDate(int)ResultSet.getDate(int, Calendar)ResultSet.getDate(String)ResultSet.getDate(String, Calendar) | 源列为 String 类型。 |
ResultSet.getTimestamp(int)ResultSet. getTimestamp(int, Calendar)ResultSet.getTimestamp(String)ResultSet.getTimestamp(String, Calendar) | 源列为 String 类型。 |
ResultSet.updateString(int, String)ResultSet.updateString(String, String) | 目标列为 DATE。 |
ResultSet.updateObject(int, String)ResultSet.updateObject(int, String, int)ResultSet.updateObject(String, String)ResultSet.updateObject(String, String, int) | 目标列为 DATE。 |
下表描述了 DBCENTURY 环境变量的四个可能值。
设置 | 含义 | 描述 |
---|---|---|
P | 过去 | 使用过去和现在的世纪来扩展年份的值。 |
F | 未来 | 使用现在和下一世纪来扩展年份的值。 |
C | 近期 | 使用过去、现在和下一世纪来扩展年份的值。 |
R | 现在 | 使用本世纪扩展年份的值。 |
有关每个设置的算法和示例的信息,请参阅《GBase 8s SQL 指南:参考》 的 "环境变量" 章节。
以下是设置 DBCENTURY 值的 URL 示例:
jdbc:gbasedbt-sqli://myhost:1533:gbasedbtserver=myserver;
user=myname;password=mypasswd;DBCENTURY=F;
URL 不能有换行符。
当 GBase 8s JDBC Driver 将 java.sql.Date 和 java.sql.Timestamp 值发送到服务器时,它通常包含四位数的年份。同样,服务器将 GBase 8s 日期值发送到 GBase 8s JDBC Driver 时,它通常包含四位数的年份。
有关如何用 GBase 8s JDBC Driver 使用 DBCENTURY ,请参阅 DBCENTURYSelect.java 、DBCENTURYSelect2.java 、DBCENTURYSelect3.java、DBCENTURYSelect4.java 和 DBCENTURYSelect5.java 示例程序。
最终用户格式的优先规则
这里列出了定义如何确定内部 DATE 值的最终用户格式的优先规则:
-
如果指定了 DBDATE 格式,则使用此格式。
-
如果指定了 GL_DATE 格式,则必须确定语言环境:
- 如果指定了 CLIENT_LOCALE 值,则与 GL_DATE 格式化字符串一起使用以显示 DATE 值。
- 如果指定了 DB_LOCALE 值,但是没有指定 CLIENT_LOCALE 值,则将 DB_LOCALE 值与数据库语言环境设置(从用户数据库的 systables 表中读取)进行比较,以验证 DB_LOCALE 值是否有效。如果 DB_LOCALE 值有效,则与 GL_DATE 格式化字符串一起使用来显示 DATE 值。如果 DB_LOCALE 值无效,则同时使用数据库语言环境和 GL_DATE 格式化字符串。
- 如果没有指定 CLIENT_LOCALE 或 DB_LOCALE 值,则同时使用数据库语言环境和 GL_DATE 格式化字符串来显示 DATE 值。
-
如果指定了 CLIENT_LOCALE 值,则 DATE 格式与此语言环境相关的缺省格式匹配。
-
如果指定了 DB_LOCALE 值,但没有指定 CLIENT_LOCALE 值,则将 DB_LOCALE 值与数据库语言环境比较来确认 DB_LOCALE 值是否有效。
如果 DB_LOCALE 值有效,则使用 DB_LOCALE 缺省格式。如果 DB_LOCALE 值无效,则使用与数据库语言环境设置关联的日期的缺省格式。
-
如果没有指定 CLIENT_LOCALE 或 DB_LOCALE 值,则所有的 DATE 值都格式化为美国英语格式:Y4MD-。
支持代码集转换
代码集转换将一种代码集的代码数据转换为另一种代码集的字符数据。在客户端/ 服务器环境中,如果客户端和数据库服务器计算机使用不同的代码集表示同一字符,则字符数据可能需要从一种代码集转换为另一种代码集。有关代码集转换的详细信息,请参阅《GBase 8s GLS 用户指南》。
必须为以下类型的字符数据指定代码集转换:
- SQL 数据类型(char 、varchar 、nchar 、nvarchar)
- SQL 语句
- 数据库对象,例如数据库名称、列名、语句标识符名称和游标名称
- 存储过程文本
- 命令文本
- 环境变量
GBase 8s JDBC Driver 转换字符数据使它能在客户机和数据库服务器之间传送。在 systables 目录中为打开的数据库指定用于转换的代码集(编码)。可以在连接属性或数据库 URL 中设置 DB_LOCALE 和 CLIENT_LOCALE 值。
数据库代码集的字符
Java™ 是基于 Unicode 的,因此 GBase 8s JDBC Driver 在 Unicode 和 GBase 8s 数据库代码集之间转换数据。代码集转换值是从连接时指定的DB_LOCALE 值中提取的。如果 DB_LOCALE 值不正确,则会发出 Database Locale information mismatch 错误。
DB_LOCALE 值必须是有效的 GBase 8s 语言环境,并具有如下表所示的有效的 GBase 8s 代码集名称。下表将支持的 JDK 1.4 编码映射到 GBase 8s 代码集。
GBase 8s 代码集名称 | GBase 8s 代码集编号 | JDK 代码集 |
---|---|---|
8859-1 | 819 | 8859_1 |
8859-2 | 912 | 8859-2 |
8859-3 | 57346 | 8859-3 |
8859-4 | 57347 | 8859-4 |
8859-5 | 915 | 8859-5 |
8859-6 | 1089 | 8859-6 |
8859-7 | 813 | 8859-7 |
8859-8 | 916 | 8859-8 |
8859-9 | 920 | 8859-9 |
ASCII | 364 | ASCII |
sjis-s | 932 | SJIS |
sjis | 57560 | SJIS |
utf-8 | 57372 | UTF8 |
big5 | 57352 | Big5 |
CP1250 | 1250 | Cp1250 |
CP1251 | 1251 | Cp1251 |
CP1252 | 1252 | Cp1252 |
CP1253 | 1253 | Cp1253 |
CP1254 | 1254 | Cp1254 |
CP1255 | 1255 | Cp1255 |
CP1256 | 1256 | Cp1256 |
CP1257 | 1257 | Cp1257 |
cp_949 | 57356 | Cp949 |
KS5601 | 57356 | Cp949 |
ksc | 57356 | Cp949 |
ujis | 57351 | EUC_JP |
gb | 57357 | ISO2022CN_GB |
GB2312-80 | 57357 | ISO2022CN_GB |
cp936 | 57357 | ISO2022CN_GB |
不能在不支持 JDK 编码的代码集中使用 GBase 8s 语言环境。此错误语法可能产生 Encoding or code set not supported 错误消息。
下表显示支持的语言环境:
支持的语言环境 | ||||
---|---|---|---|---|
ar_ae | ar_bh | ar_kw | ar_om | ar_qa |
ar_sa | bg_bg | ca_es | cs_cz | da_dk |
de_at | de_ch | de_de | el_gr | en_au |
en_ca | en_gb | en_us | en_nz | ar_ae |
es_ar | es_bo | es_co | es_cl | es_cr |
es_ec | es_es | es_gt | es_mx | es_pa |
es_pe | es_py | es_sv | es_uy | es_ve |
fi_fi | fr_be | fr_ca | fr_ch | fr_fr |
hr_hr | hu_hu | is_is | it_ch | it_it |
iw_il | ja_jp | ko_kr | mk_mk | nl_be |
nl_nl | no_no | pl_pl | pt_br | pt_pt |
ro_ro | ru_ru | sh_yu | sk_sk | sv_se |
th_th | tr_tr | uk_ua | zh_cn | zh_tw |
客户端代码集 Unicode
因为 Unicode 代码集包含所有的现有代码集,所以 Java™ 虚拟机(JVM)必须提供平台语言环境代码集的字符。在 Java 程序内,您必须始终使用 Unicode 字符。在那个平台上的 JVM 在 Unicode 和语言环境代码集之间转换输入和输出。
例如,您在 Unicode 指定按钮标签,则 JVM 转换文本以正确地指示标签。同样,当 getText() 方法从文本框获取到用户的输入时,无论用户如何输入,客户端应用程序都将获得 Unicode 格式的字符串。
切勿一次读取一个字节的文本文件。始终使用 InputStreamReader() 或 OutputStreamWriter() 方法操纵文本文件。缺省情况下,这些方法使用本地语言环境编码,但是您可以在类的构造函数中指定编码方式,如下所示:
InputStreamReader = new InputStreamReader (in, "SJIS");
您和 JVM 负责将外部输入转换为正确的 Java Unicode 字符串。此后,使用数据库区域设置编码将数据发送到数据库服务器或从数据库服务器发送数据。
连接具有非 ASCII 字符的数据库
如果您在连接时没有指定数据库名称,则连接必须使用正确的指定数据库的 DB_LOCALE 值打开。
如果关闭数据库并发出了数据库 dbname 语句,则连接继续使用初始的 DB_LOCALE 值解释数据库名称。如果新数据库的 DB_LOCALE 值不符合,则返回错误。在此情况下,客户端程序必须关闭,并使用正确的新数据库的 DB_LOCALE 值重新打开连接。
如果您在连接时提供数据库名称,则 DB_LOCALE 值必须设置为正确的数据库语言环境。
可以通过使用 NEWCODESET 和 NEWLOCALE 连接属性定义语言环境,来连接到 NLS 数据库。有关它们的格式,请参阅 Connecting with the NEWLOCALE and NEWCODESET Environment Variables 。
TEXT 和 CLOB 数据类型的代码集转换
GBase 8s JDBC Driver 不会自动在 TEXT 、BYTE 、CLOB 和 BLOB 数据类型的代码集之间进行转换。
可以使用以下方式在 TEXT 和 CLOB 数据类型的代码集之间进行转换:
- 可以通过使用 IFX_CODESETLOB 环境变量自动化客户端和数据库语言环境之间的 TEXT 或 CLOB 数据的代码集转换。
- 可以使用 getBytes() 、getString() 、InputStreamReader() 和 OutputStreamWriter() 方法在 TEXT 数据代码集之间进行转换。
使用 IFX_CODESETLOB 环境变量转换
可以自动转换 TEXT 和 CLOB 数据类型的代码集对:
- 在将数据发送到数据库服务器之前从客户端语言环境转换到数据库语言环境。
- 在客户端检索数据之前,从数据库语言环境转换到客户端语言环境。
要自动化 TEXT 和 CLOB 数据类型的代码集之间的转换,请在连接 URL 中使用 IFX_CODESETLOB 环境变量。例如:IFX_CODESETLOB = 4096。还可以使用以下 IfxDataSource 类的方法来设置和获取 IFX_CODESETLOB 值:
public void setIfxIFX_CODESETLOB(int codesetlobFlag);
public int getIfxIFX_CODESETLOB();
IFX_CODESETLOB 可以具有以下值:
none
缺省值 不启用自动转换代码集。
0 在内部临时文件中发生自动转换代码集。
> 0 在客户端计算机的内存中发生自动转换代码集。该值指示分配给转换的字节数。
如果分配的字节数小于大对象的大小,则返回错误。
要在内存中执行转换,必须指定一个小于客户机的内存限制的量,并且大于任何已转换大对象的可能大小。
当您使用以下 java.sql.Clob 接口方法或 Clob 接口的 GBase 8s 扩展中的任何一种时,即使设置了 IFX_CODESETLOB 环境变量,也不会执行代码集转换。这些方法包括:
IfxCblob::setAsciiStream(long) Clob::setAsciiStream(long position, InputStream fin, int length)
IFX_CODESETLOB 仅对来自 java.sql.PreparedStatement 接口的方法生效。
但是,在使用以下 java.sql.Clob 接口方法或 Clob 接口的 GBase 8s 扩展时,Unicode 字符总是自动转换为数据库语言环境代码集。以下是这些方法的列表:
Clob::setCharacterStream(long) throws SQLException
Clob::setString(long, String) throws SQLException
Clob:: setString(long pos, String str, int offset, int len)
IfxCblob::setSubString(long position, String str, int length)
使用 JDK 方法转换
getBytes() 、getString() 、InputStreamReader() 和 OutputStreamWriter() 方法接受一个代码集参数,该参数可以在 Unicode 与指定的代码集之间相互转换
以下样例代码显示了如何将客户端代码集中的文件转换为 Unicode,然后将其从 Unicode 转换为数据库代码集:
File infile = new File("data_jpn.dat");
File outfile = new File ("data_conv.dat");..
.pstmt = conn.prepareStatement("insert into t_text values (?)");..
.// Convert data from client encoding to database encoding
System.out.println("Converting data ...\n");
try
{
String from = "SJIS";
String to = "8859_1";
convert(infile, outfile, from, to);
}
catch (Exception e)
{
System.out.println("Failed to convert file");
}
System.out.println("Inserting data ...\n");
try
{
int fileLength = (int) outfile.length();
fin = new FileInputStream(outfile);
pstmt.setAsciiStream(1 , fin, fileLength);
pstmt.executeUpdate();
}
catch (Exception e)
{
System.out.println("Failed to setAsciiStream");
}..
.public static void convert(File infile, File outfile, String from, String to)
throws IOException
{
InputStream in = new FileInputStream(infile);
OutputStream out = new FileOutputStream(outfile);
Reader r = new BufferedReader( new InputStreamReader( in, from));
Writer w = new BufferedWriter( new OutputStreamWriter( out, to));
//Copy characters from input to output. The InputStreamReader converts
// from the input encoding to Unicode, and the OutputStreamWriter
// converts from Unicode to the output encoding. Characters that can
// not be represented in the output encoding are output as '?'
char[] buffer = new char[4096];
int len;
while ((len = r.read(buffer)) != -1)
w.write(buffer, 0, len);
r.close();
w.flush();
w.close();
}
当从数据库检索数据时,可以使用相同的方法将数据从数据库代码集转换为客户端代码集。
BLOB 和 BYTE 数据类型的代码集转换
当您使用 java.sql.PreparedStatement::setCharacterStream() 向 CLOB 列插入时,Java™ Unicode 字符会自动转换为数据库语言环境代码集。如果设置了环境变量IFX_CODESETLOB,则它的值确定是使用临时文件执行代码集转换还是在内存中执行代码集转换。如果未设置 IFX_CODESETLOB,则LOBCACHE 环境变量确定在临时文件中还是在内存中执行代码集转换。
但是,不鼓励您使用 java.sql.PreparedStatement::setCharacterStream() 来插入 BLOB 或 BYTE 列。JDBC 驱动程序不能将 Java 字符插入到数据库中,因此会尝试对字符进行行代码集转换。使用 java.sql.PreparedStatement::setBinaryStream() 是插入 BLOB 或 BYTE 列的首选方式。
用户定义的语言环境
GBase 8s JDBC Driver 使用 JDK 全球化 API 操纵国际数据。此 API 中的类和方法将 JDK 语言环境或编码作为参数,但是因为 GBase 8s DB_LOCALE和 CLIENT_LOCALE属性指定基于 GBase 8s 名称的语言环境和代码集,所以这些 GBase 8s 名称将映射到 JDK 名称。这些映射保存在定期更新的内部表中。
例如,ASCII 代码集的 GBase 8s 和 JDK 名称分别是 8859-1 和 8859_1。GBase 8s JDBC Driver 在其内部表中映射 8859-1 到 8859_1,并在 JDK 类和方法中使用适当的 JDK 名称。
使用 NEWLOCALE 和 NEWCODESET 环境变量连接
因为可能在这些表的更改之间创建新的语言环境,所以可以使用两个连接属性 NEWLOCALE 和 NEWCODESET 来指定表中未指定的语言环境或代码集。以下是 URL 使用这些属性的示例:
jdbc:gbasedbt-sqli://myhost:1533:gbasedbtserver=myserver;
user=myname; password=mypasswd;NEWLOCALE=en_us,en_us;
NEWCODESET=8859_1,8859-1,819;
URL 必须是一行。
NEWLOCALE 和 NEWCODESET属性具有以下格式:
NEWLOCALE=JDK-locale,Ifx-locale:JDK-locale,Ifx-locale...
NEWCODESET=JDK-encoding,Ifx-codeset,Ifx-codeset-number:JDK-encoding, Ifx-codeset,Ifx-codeset-number...
指定的代码集或语言环境映射的数量没有限制。
可以通过使用 NEWCODESET 和 NEWLOCALE 连接属性连接到 NLS 数据库。
如果指定的参数或值的数量不正确,则会显示 Locale Not Supported 或 Encoding or Code Set Not Supported 消息。
如果在 URL 或DataSource 对象中设置这些属性,则 NEWCODESET 和 NEWLOCALE 的新值会覆盖 JDBC 内部表中的值。例如,如果 JDBC 已经在内部映射了 8859-1 到 8859_1,但是您指定 NEWCODESET=8888,8859-1,819,则代码集转换时使用新值 8888。
使用 NEWNLSMAP 环境变量连接
要支持连接到 NLS 数据库,则 GBase 8s JDBC Driver 维护一个将 NLS 语言环境映射到对应的 JDK 语言环境和 JDK 代码集的表。随着 JDK 支持使更多的语言环境和代码集可用,NLS 语言环境之前不支持的语言环境和代码集在新的 JDK 中支持。GBase 8s JDBC Driver 支持连接属性 NEWNLSMAP ,可以使用它指定映射没有在表中指定的 NLS 语言环境。
NEWNLSMAP 属性具有以下格式:
NEWNLSMAP=NLS-locale,JDK-locale,JDK-codeset:NLS-locale,JDK-locale,JDK-codeset,....
以下是 URL 使用这些属性的示例:
jdbc:gbasedbt-sqli://myhost:1533:gbasedbtserver=myserver;
user=myname;password=mypasswd;NEWNLSMAP=rumanian,ro_RO,ISO8859_2;
指定的代码集或语言环境映射的数量没有限制。如果指定的参数或值的数量不正确,则会显示 Locale Not Supported 或 Encoding or Code Set Not Supported 消息。
支持全球化的错误消息
消息文本通常是 SQLException 对象的文本,但也可以是 SQLWarn 对象或任何其它来自驱动程序的文本输出。
启用全球化消息文本输出有两个要求,如下所示:
- 必须将 gbasedbtjdbc_xx.jar 文件的完整路径名添加到 $CLASSPATH(UNIX™)或 %CLASSPATH%(Windows™)环境变量。此 JAR 文件包含GBase 8s JDBC Driver 支持的所有全球化版本的消息文本。支持的语言是英语和中文。
- 如果您使用的是非缺省语言环境,则 CLIENT_LOCALE环境变量值必须在连接时通过属性列表传递给连接对象。有关一般的 CLIENT_LOCALE 和 GLS 功能,请参阅 支持 GBase 8s GLS 变量.
多个公共类具有将当前连接对象作为参数的构造函数,以便可以直接存取 CLIENT_LOCALE 值。如果您希望访问非英文的错误消息,则必须使用包含此连接对象的构造函数。否则,任何来自这些类的消息文本仅为英文。受影响的公共类为 Interval 、IntervalYM 、IntervalDF 和 IfxLocator。有关这些类的构造函数的更多信息,请参阅 操作 GBase 8s 类型。
有关如何使用全球化错误消息支持功能的示例,请参阅 GBase 8s JDBC Driver 附带的 locmsg.java 程序。