關於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/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 關於一類資料處理
- 關於資料庫事務併發的理解和處理資料庫
- 關於 Eloquent ORM 對資料處理的思考ORM
- [python] 基於Tablib庫處理表格資料Python
- 關於SQL Serve資料庫r帳號被禁用的處理方法SQL資料庫
- 支付類系統資料處理和資料中臺的資料處理方式有什麼不同?
- [20210722]資料庫異常關閉的處理.txt資料庫
- 快手關於海量模型資料處理的實踐模型
- java大資料處理:如何使用Java技術實現高效的大資料處理Java大資料
- 教你如何運用python實現不同資料庫間資料同步功能Python資料庫
- [影像處理] 基於CleanVision庫清洗影像資料集
- Python資料處理(二):處理 Excel 資料PythonExcel
- 資料庫同步資料庫
- 3.3.1 關於關閉資料庫資料庫
- mysql,sqlserver資料庫單表資料過大的處理方式MySqlServer資料庫
- Polars提供Javascript的資料處理庫 - levelupJavaScript
- 資料庫系列——基於Canal實現MySQL增量資料同步資料庫MySql
- 2.1 關於建立資料庫資料庫
- DataX將MySql資料庫資料同步到Oracle資料庫MySql資料庫Oracle
- 資料處理
- [資料整合/資料同步] 基於資料庫增量日誌的資料同步方案 : Flink CDC/Debezium/DataX/Canal/Oracle Goldengate/Kettle/Sqoop資料庫OracleGoOOP
- 關於丟失表空間資料檔案的處理方式
- 資料分析--資料預處理
- 資料預處理-資料清理
- 資料清洗和資料處理
- 修改Oracle資料庫字符集(zt)Oracle資料庫
- 2.5.1 關於建立資料庫的子句資料庫
- 關於資料庫鎖的總結資料庫
- ES同步Mysql資料庫(包括出現問題怎麼處理哦)MySql資料庫
- 基於python的大資料分析-資料處理(程式碼實戰)Python大資料
- 關於同一個連線不同資料庫之間的 Eloquent 關聯查詢資料庫
- DataX將Oracle資料庫資料同步到達夢資料庫Oracle資料庫
- 還原sql server 2000資料庫的坑,不同版本資料庫SQLServer資料庫
- 剖析大資料平臺的資料處理大資料
- 2.8.1.1 關於資料庫服務資料庫
- 亞信安慧AntDB資料庫——實時流資料處理的先鋒資料庫
- Dede呼叫資料庫失敗,無法實現資料處理資料庫
- 資料預處理-資料歸約
- 海量資料處理