请问nodejs-mysql-native 如何访问非utf8字符集的数据库
发布于 2年前 作者 cckowin 2165 次浏览

数据库表如下

CREATE TABLE `um_department` (
     `deptid` int(11) NOT NULL AUTO_INCREMENT,
     `dept` varchar(64) NOT NULL DEFAULT '',
      `dupid` int(11) DEFAULT '0',
     `deptshow` varchar(127) DEFAULT '',
      PRIMARY KEY (`deptid`)
) ENGINE=MyISAM AUTO_INCREMENT=74 DEFAULT CHARSET=gbk

采用下面方法访问的结果显示的是乱码

 db=require("mysql-native").createTCPClient(config.dbHost);
 db.auto_prepare=true;
 db.auth(config.dbNameofApp,config.dbPass,config.dbUser);
 db.query("set names gbk");
 app.get('/test', function(req, res) {
     var rest = [];
     db.query("use " + config.dbNameofApp);
     db.query("SELECT * from um_department where dupid = '1'")
         .on("row", function(r) {
             rest.push({
                 deptid: r.deptid,
                 dept: r.dept,
                 dupid: r.dupid,
                 deptshow: r.deptshow
             });
         })
         .on("end", function(r) {
             res.end(JSON.stringify(rest));
         });
 });

请问如何访问呢才能正常显示中文呢

8 回复

iconv-lite转码成UTF8就行了。GBK的nodejs目前还不支持。

是不是采用这种形式

db.query("SELECT * from um_department where dupid = '1'")
    .on("row", function(r) {
        rest.push({
            deptid: r.deptid,
            dept: r.dept,
            dupid: r.dupid,
            deptshow: r.deptshow
        });
    })
    .on("end", function(r) {
        var buffer = new Buffer(JSON.stringify(rest));
        console.log(iconv.decode(JSON.stringify(rest), 'gbk'));
    });

但是还是乱码 我新建了个表

CREATE TABLE `test` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `value` varchar(10) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=gbk;

在里面插入了一条数据

insert into test value(1, "你好");

然后查询

db.query("SELECT * from test where id = '1'")
    .on("row", function(r) {
        var buffer = new Buffer(r.value);
        console.log(buffer);
    });

输出

<Buffer c3 84 c3 a3 c2 ba c3 83>

但是你好的gbk编码是c4e3 bac3,utf8编码是e4bd a0e5 a5bd我不知道我查出来的数据是啥编码了

你这样是不行的 因为mysql在取数据的时候就已经转成utf8 你在收到之后转换是没用的 我是用node-mysql,在接收包的时候就先判断编码直接转换 转换我是用iconv不是lite

那请问在哪里修改呢,在哪能取到未转化前的数据呢,还有顺便问一下如何插入中文数据啊,是不是也有问题啊,谢谢

模块代码也很长时间没维护了,所以看了一下这个模块的代码,从‘socketclient.js’里收到数据后就内部转码了。本来说找一下从哪一处开始,但是我得到的数据不管写什么已经都是3f了没有像你的那个一样,还有正常的码,不知道是什么问题。插入时用php和模块自带例子都试了。

{ id: 1, value: '??' }
<Buffer 3f 3f>

@cckowin 而且这个模块我也没用过,你换node-mysql试试吧,这个支持gbk的。 node原生不支持,所以插入和读出来的时候可能需要转码。

@saighost 谢谢帮忙,你得到的结果是

{ id: 1, value: '??' }
<Buffer 3f 3f>

是因为查询前没有加上这行代码 db.query(“set names gbk”);

刚才在看node-mysql-native的原代码的时候发现了这行代码

this.connection.setEncoding("binary");

原来它是把数据读到string,而不是buffer中的,试了一下直接访问string 的每个字符string.charAtCode(i),发现成功了

db.query("SELECT * from test where id = '1'")
    .on("row", function(r) {
        var buf = new Buffer(r.value.length);
        for(var i=0; i<r.value.length; ++i) {
            buf[i] = r.value.charCodeAt(i);
        }
        console.log(buf);
        var str = iconv.decode(buf, 'gbk');
        console.log(str);
    });

结果如下

<Buffer c4 e3 ba c3>
你好

@cckowin 我建议可以fork然后改一下他的socketclient,这样就不用每次这么麻烦了。插入那个的话他有一些测试,你可以参考他的测试代码。

回到顶部