请问Nodejs的nodejs-mysql-native如何访问非utf8字符集的数据库

请问Nodejs的nodejs-mysql-native如何访问非utf8字符集的数据库

数据库表如下

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));
         });
 });

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


5 回复

要解决Node.js中的nodejs-mysql-native库在访问非UTF-8字符集(如GBK)的数据库时出现乱码问题,你需要确保客户端与服务器端的字符编码一致。这可以通过在连接到数据库后立即执行SQL命令来设置字符集。

以下是修正后的示例代码:

const mysqlNative = require("mysql-native");
const db = mysqlNative.createTCPClient(config.dbHost);

db.auto_prepare = true;

// 连接到数据库之前,先设置字符集为GBK
db.on('connect', () => {
    db.query("SET NAMES gbk");
});

db.auth(config.dbNameofApp, config.dbPass, config.dbUser);

app.get('/test', function(req, res) {
    const rest = [];
    
    // 使用指定的数据库
    db.query("USE " + config.dbNameofApp)
        .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() {
            res.end(JSON.stringify(rest));
        });
});

解释

  1. 连接事件处理:

    • 在连接到数据库之后立即执行SET NAMES gbk语句,以确保客户端与服务器端的字符集一致。
  2. 查询操作:

    • 首先使用USE语句选择数据库。
    • 然后执行具体的SQL查询语句。

通过这种方式,可以确保从数据库中获取的数据以正确的字符集进行解码,避免乱码问题。


是不是采用这种形式

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

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

为了确保使用 nodejs-mysql-native 正确访问非 UTF-8 字符集(如 GBK)的数据库并避免乱码问题,需要确保客户端和服务器端的字符编码一致。以下是一些步骤和示例代码,可以帮助你解决这个问题:

  1. 设置连接时的字符集:在连接数据库时显式地指定字符集。
  2. 执行 SET NAMES 命令:确保查询时使用的字符集正确。

以下是修改后的代码示例:

const mysql = require("mysql-native");

// 创建数据库连接
const db = mysql.createTCPClient({
    host: config.dbHost,
    charset: 'gbk' // 显式指定字符集为 gbk
});

db.auto_prepare = true;

// 连接数据库
db.auth(config.dbNameofApp, config.dbPass, config.dbUser);

app.get('/test', function(req, res) {
    let rest = [];

    // 使用正确的数据库
    db.query("USE " + config.dbNameofApp)
        .then(() => {
            return new Promise((resolve, reject) => {
                db.query("SET NAMES gbk") // 设置字符集为 gbk
                    .then(() => {
                        resolve();
                    })
                    .catch(reject);
            });
        })
        .then(() => {
            return new Promise((resolve, reject) => {
                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() {
                        res.end(JSON.stringify(rest));
                        resolve();
                    })
                    .catch(reject);
            });
        })
        .catch(err => {
            console.error(err);
            res.status(500).send("Database error");
        });
});

关键点:

  • 在创建 TCP 客户端时显式指定 charset'gbk'
  • 执行 SET NAMES gbk 确保查询时使用的字符集为 GBK。
  • 使用 Promise 处理异步操作,确保在每个步骤完成后继续下一个操作。

这样可以确保数据以正确的字符集进行传输和解析,从而避免乱码问题。

回到顶部