關於java處理不同資料庫字符集的資料同步
環境:
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/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 不同字符集資料庫之間的資料同步問題:資料庫
- 不同字符集資料庫之間的資料同步問題-補資料庫
- 關於資料庫字符集資料庫
- 不同Oracle資料庫之間的資料同步Oracle資料庫
- 使用物化檢視實現在不同字符集的資料庫之間的資料同步資料庫
- 關於批處理(bat)資料庫備份BAT資料庫
- java處理資料庫date型別資料Java資料庫型別
- 關於裸裝置資料的處理
- 同步整合不同系統、不同資料庫中資料的問題資料庫
- 基於ORM思想的資料庫處理ORM資料庫
- 關於資料庫事務併發的理解和處理資料庫
- 關於資料庫操作多個操作組合的處理資料庫
- 在不同字符集的資料庫之間匯入資料的方法(轉)資料庫
- 關於 Eloquent ORM 對資料處理的思考ORM
- 一個關於資料庫閃回區問題的處理資料庫
- 支付類系統資料處理和資料中臺的資料處理方式有什麼不同?
- 關於SQL Serve資料庫r帳號被禁用的處理方法SQL資料庫
- 關於java連線SQL資料庫JavaSQL資料庫
- 快手關於海量模型資料處理的實踐模型
- Solr資料不同步Solr
- 關於異地資料同步的方案
- java大資料處理:如何使用Java技術實現高效的大資料處理Java大資料
- 資料庫如何處理大資料訪問資料庫大資料
- JAVA資料庫處理(連線,資料查詢,結果集返回)Java資料庫
- 資料庫壞塊處理資料庫
- zabbix資料庫日常處理資料庫
- 誤刪資料庫資料檔案的處理方法資料庫
- 關於海量資料處理分析的經驗總結
- 2 關於資料倉儲維度資料處理的方法探究系列——無變化維度處理
- 資料庫timesten與 oracle 處理日期上寫法上的不同資料庫Oracle
- 關於資料庫故障資料庫
- 關於大資料和資料庫的討論大資料資料庫
- 9 關於資料倉儲維度資料處理的方法探究系列——雪花維
- [python] 基於Tablib庫處理表格資料Python
- 1 關於資料倉儲維度資料處理的方法探究系列——維的概述
- 資料庫同步資料庫
- mysql 資料不同字符集遷移步驟MySql
- 教你如何運用python實現不同資料庫間資料同步功能Python資料庫