解决MySQL数据库数据导出乱码问题

       最近在做MySQL数据导出到HBase中的任务,刚开始以为很简单,但后来发现坑比较多。主要是由于历史原因存在着不同的字符集格式。为了能为后面数据分析提供基础,需要对导出的数据统一编码成UTF-8

      采用jdbc方式读取数据,连接字符串设置编码格式utf-8,查询数据前首先需要执行下executeQuery("set names utf8"); 对于一次查询请求,信息输入路径:client→connection→server;信息输出路径:server→connection→results。换句话说,每个路径要经过3次改变字符集编码。以出现乱码的输出为例,server里utf8的数据,传入connection转为latin1,传入 results转为latin1,utf-8页面又把results转过来。如果两种字符集不兼容,比如latin1和utf8,转化过程就为不可逆的, 破坏性的。

      我所接触到的遗留库主要是latin1和utf-8两种字符集的, 需要根据情况进行转码。既可以根据表的TABLE_COLLATION来断定(如select TABLE_SCHEMA, TABLE_NAME, TABLE_COLLATION, ENGINE from tables where TABLE_SCHEMA = "haitao" and table_name = "haitao_user_biz_deal_withdrawals), 如果是utf8_general_ci 的无需处理,如果是latin1_swedish_ci,则按照如下方式来处理:

sql 的latin1 不等于标准的latin1(iso-8859-1) 和cp1252,比iso-8859-1多了0x80-0x9f字符,比cp1252多了0x81,0x8d,0x8f,0x90,0x9d 一共5个字符。
这样在Java中,如果使用标准的iso-8859-1或者cp1252解码可能出现乱码。
s.getBytes("iso-8859-1") 或者 s.getBytes("cp1252");


写了一段代码来解决这个问题
private String convertCharset(String s){
        if(s!=null){
            try {
                int length = s.length();
                byte[] buffer = new byte[length];
                //0x81 to Unicode 0x0081, 0x8d to 0x008d, 0x8f to 0x008f, 0x90 to 0x0090, and 0x9d to 0x009d.
                for(int i=0;i<length;++i){
                    char c = s.charAt(i);
                    if(c==0x0081){
                        buffer[i]=(byte)0x81;
                    }
                    else if(c==0x008d){
                        buffer[i]=(byte)0x8d;
                    }
                    else if(c==0x008f){
                        buffer[i]=(byte)0x8f;
                    }
                    else if(c==0x0090){
                        buffer[i]=(byte)0x90;
                    }
                    else if(c==0x009d){
                        buffer[i]=(byte)0x9d;
                    }
                    else{
                        buffer[i] = Character.toString(c).getBytes("cp1252")[0];
                    }
                }
                String result = new String(buffer,"utf-8");
                return result;
            } catch (UnsupportedEncodingException e) {
                logger.error("charset convert error", e);
            }
        }
        return null;
    }

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值