如何在nodejs中的单个文件中提供mysql数据库连接

use*_*476 44 mysql node.js express node-modules

我需要为模块提供mysql连接.我有这样的代码.

var express = require('express'),
app = express(),
server = require('http').createServer(app);

var mysql      = require('mysql');
var connection = mysql.createConnection({
    host     : '127.0.0.1',
    user     : 'root',
    password : '',
    database    : 'chat'
});

connection.connect(function(err) {
    if (err) {
        console.error('error connecting: ' + err.stack);
        return;
    }
});

app.get('/save', function(req,res){
    var post  = {from:'me', to:'you', msg:'hi'};
    var query = connection.query('INSERT INTO messages SET ?', post, function(err, result) {
        if (err) throw err;
    });
});

server.listen(3000);
Run Code Online (Sandbox Code Playgroud)

但是我们如何为所有模块提供一次mysql连接.

Sea*_*n3z 136

您可以创建一个db包装器然后需要它.node's require每次都返回一个模块的同一个实例,因此您可以执行连接并返回一个处理程序.来自Node.js文档:

每次调用require('foo')将获得完全相同的返回对象,如果它将解析为同一个文件.

你可以创建db.js:

var mysql = require('mysql');
var connection = mysql.createConnection({
    host     : '127.0.0.1',
    user     : 'root',
    password : '',
    database : 'chat'
});

connection.connect(function(err) {
    if (err) throw err;
});

module.exports = connection;
Run Code Online (Sandbox Code Playgroud)

然后在你的app.js,你只需要它.

var express = require('express');
var app = express();
var db = require('./db');

app.get('/save',function(req,res){
    var post  = {from:'me', to:'you', msg:'hi'};
    db.query('INSERT INTO messages SET ?', post, function(err, result) {
      if (err) throw err;
    });
});

server.listen(3000);
Run Code Online (Sandbox Code Playgroud)

这种方法允许您抽象任何连接细节,db在整个应用程序中包含您想要公开和需要的任何其他内容,同时保持与数据库的一个连接,这要归功于节点需要如何工作:)

  • @ Sean3z你确定`connection.connect()`每次文件是`require`d时都不会创建连接吗? (5认同)
  • 连接池比使用单个连接更优化。相同的模式可用于连接池。参考 [this](https://github.com/mysqljs/mysql#pooling-connections) 实现。 (3认同)
  • 我意识到我参加聚会有点晚了,但是将 db.js 文件放在 express 应用程序中的常规位置是什么? (2认同)
  • 请告诉我,没有关闭连接不会消耗大量内存? (2认同)
  • 在 Windows 上,这个约定有一个特殊情况需要注意:(1) node.js 根据传递给 require() 的字符串缓存导出,并且这个字符串缓存区分大小写;(2) 由于 Windows 路径不区分大小写,这实际上会创建 2 个 db 连接实例。只要您的 require 语句在所有文件中的大小写相同,这就不成问题。 (2认同)

Raf*_*ael 14

我采用了与Sean3z类似的方法,但每次我进行查询时都会关闭连接.

如果它只在你的应用程序的入口点执行,他的方式可行,但是假设你有你想做的控制器var db = require('./db').您不能,因为否则每次访问该控制器时,您都将创建一个新连接.

为了避免这种情况,我认为在每次打开和关闭连接时更安全.

这是我的代码片段.

mysq_query.js

// Dependencies
var mysql   = require('mysql'),
    config  = require("../config");

/*
 * @sqlConnection
 * Creates the connection, makes the query and close it to avoid concurrency conflicts.
 */
var sqlConnection = function sqlConnection(sql, values, next) {

    // It means that the values hasnt been passed
    if (arguments.length === 2) {
        next = values;
        values = null;
    }

    var connection = mysql.createConnection(config.db);
    connection.connect(function(err) {
        if (err !== null) {
            console.log("[MYSQL] Error connecting to mysql:" + err+'\n');
        }
    });

    connection.query(sql, values, function(err) {

        connection.end(); // close the connection

        if (err) {
            throw err;
        }

        // Execute the callback
        next.apply(this, arguments);
    });
}

module.exports = sqlConnection;
Run Code Online (Sandbox Code Playgroud)

你可以在任何地方使用它

var mysql_query = require('path/to/your/mysql_query');
mysql_query('SELECT * from your_table where ?', {id: '1'}, function(err, rows)   {
    console.log(rows);
});
Run Code Online (Sandbox Code Playgroud)

更新: config.json看起来像

{
        "db": {
        "user"     : "USERNAME",
        "password" : "PASSWORD",
        "database" : "DATABASE_NAME",
        "socketPath": "/tmp/mysql.sock"
    }
}
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助.