關於java處理不同資料庫字符集的資料同步

Steven1981發表於2008-09-28
兩個資料庫字符集不一樣,如何快速增量同步資料.[@more@]

環境:

DB-A 字符集:US7ASCII
DB-B 字符集:ZHS16GBK

需求: 從DB-A中將一個表的中文資料透過JAVA定時任務同步到DB-B.

DB-A庫中表的資訊如下:
CREATE TABLE USER_INFO (USER_ID number, USER_NAME varchar2(50));

如果用一般的方式來SELECT,和INSERT,不管客戶端用什麼樣的字符集,資料到DB-B上肯定會顯示亂碼.

解決方法1 (在資料庫實現)

解決思路:透過檢視將資料轉換成二進位制資料,繞過字符集的轉換,然後讓目標庫來讀取.
1. 在DB-A庫上建立檢視:
create or replace view view_user_info
as
select user_id, utl_raw.cast_to_raw(user_name) user_name from user_info ;

2. 在DB-B庫上建立檢視:
create or replace view view_user_info_db_a
as
select user_id, utl_raw.cast_to_varchar2 (user_name) user_name from
;

3. 在DB-B庫上進行資料讀取:
select user_id,user_name from view_user_info_db_a ;
這時顯示出來的資料才是正確的!

其實就是:select utl_raw.cast_to_raw('中華人民'),utl_raw.cast_to_varchar2('D6D0BBAAC8CBC3F1') from dual;
優點: 對JAVA程式來說是透明的,無所改動程式碼。
資料提取時,與客戶端字符集無關
缺點: 增加資料庫CPU開銷

--經過鍾MM的提示學習到了以下方法:

解決方法2 (在JAVA實現)

使用JAVA的兩個函式來實現:getBytes() , new String()
先來看一下這兩個函式:

. getBytes(charset)

這是java字串處理的一個標準函式,其作用是將字串所表示的字元按照charset編碼,並以位元組方式表示。
注意字串在java記憶體中總是按unicode編碼儲存的。
比如"中文",正常情況下(即沒有錯誤的時候)儲存為"4e2d 6587",
如果charset為"gbk",則被編碼為"d6d0 cec4",然後返回位元組"d6 d0 ce c4"。
如果charset為"utf8"則最後是"e4 b8 ad e6 96 87"。
如果是"iso8859-1",則由於無法編碼,最後返回 "3f 3f"(兩個問號)。

. new String(charset)

這是java字串處理的另一個標準函式,和上一個函式的作用相反,將位元組陣列按照charset編碼進行組合識別,最後轉換為unicode儲存。
參考上述getBytes的例子,"gbk" 和"utf8"都可以得出正確的結果"4e2d 6587",但iso8859-1最後變成了"003f 003f"(兩個問號)。
因為utf8可以用來表示/編碼所有字元,所以new String( str.getBytes( "utf8" ), "utf8" ) === str,即完全可逆。

對於以上兩個函式,我們可以有兩種用法來解決這個問題:
方法 2.1

a) 無需關心客戶端NLS_LANG的設定
b) 從資料庫取出字元的二進位制編碼:
select user_id, utl_raw.cast_to_raw(user_name) user_name from user_info ;
c) 在java用其所 new String(username, 'GBK' ) 轉成中文
d) 插入到目標庫

方法 2.2 (推薦)

a) 將JAVA 客戶端NLS_LANG設定為US7ASCII
b) 從資料庫直接取出欄位值
select user_id, user_name from user_info ;
(這時因為客戶端和伺服器的字符集一致,所以會得到正確的中文顯示)
c) 將中文進行轉碼為GBK:
new String( user_name.getBytes( "gbk" ), "gbk" )
d) 得到正確的GBK中文編碼插入到目標庫

優點:程式碼完全由JAVA控制,無需作資料庫變更,資料庫的壓力轉移到了JAVA客戶端.
注意:必須把客戶端的字符集和伺服器端的字符集設定成一樣


大家拍磚.

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/703656/viewspace-1011210/,如需轉載,請註明出處,否則將追究法律責任。

相關文章