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

问题描述 投票:0回答:8

我需要为模块提供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);

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

mysql node.js express node-modules
8个回答
175
投票

您可以创建一个数据库包装器然后需要它。节点的 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;

然后在您的

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

这种方法允许您抽象任何连接详细信息,包装您想要在整个应用程序中公开和需要的任何其他内容

db
,同时由于节点 require 的工作方式而保持与数据库的一个连接:)


20
投票

我采用了与 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;

您可以在任何地方使用它,就像这样

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

更新: config.json 看起来像

{
        "db": {
        "user"     : "USERNAME",
        "password" : "PASSWORD",
        "database" : "DATABASE_NAME",
        "socketPath": "/tmp/mysql.sock"
    }
}

希望这有帮助。


3
投票

我认为你应该使用连接池而不是共享单个连接。连接池将提供更好的性能,您可以查看here

如库文档中所述,发生这种情况是因为 MySQL 协议是顺序的(这意味着您需要多个连接来并行执行查询)。

连接池文档


1
投票

根据node.js文档,“要让模块多次执行代码,导出函数并调用该函数”,您可以使用node.js module.export并使用单个文件来管理数据库连接。您可以在 Node.js 文档 中找到更多信息。假设 db.js 文件如下:

    const mysql = require('mysql');

    var connection;

    module.exports = {

    dbConnection: function () {

        connection = mysql.createConnection({
            host: "127.0.0.1",
            user: "Your_user",
            password: "Your_password",
            database: 'Your_bd'
        });
        connection.connect();
        return connection;
    }

    };

然后,您要使用连接的文件可能类似于 useDb.js:

const dbConnection = require('./db');

var connection;

function callDb() {

    try {

        connection = dbConnectionManager.dbConnection();

        connection.query('SELECT 1 + 1 AS solution', function (error, results, fields) {
            if (!error) {

                let response = "The solution is: " + results[0].solution;
                console.log(response);

            } else {
                console.log(error);
            }
        });
        connection.end();


    } catch (err) {
        console.log(err);
    }
}

1
投票
var mysql = require('mysql');

var pool  = mysql.createPool({
    host     : 'yourip',
    port    : 'yourport',
    user     : 'dbusername',
    password : 'dbpwd',
    database : 'database schema name',
    dateStrings: true,
    multipleStatements: true
});


// TODO - if any pool issues need to try this link for connection management
// https://stackoverflow.com/questions/18496540/node-js-mysql-connection-pooling

module.exports = function(qry, qrytype, msg, callback) {

if(qrytype != 'S') {
    console.log(qry);
}

pool.getConnection(function(err, connection) {
    if(err) {
        if(connection)
            connection.release();
        throw err;
    } 

    // Use the connection
    connection.query(qry, function (err, results, fields) {
        connection.release();

        if(err) {
            callback('E#connection.query-Error occurred.#'+ err.sqlMessage);    
            return;         
        }

        if(qrytype==='S') {
            //for Select statement
            // setTimeout(function() {
                callback(results);      
            // }, 500);
        } else if(qrytype==='N'){
            let resarr = results[results.length-1];
            let newid= '';
            if(resarr.length)               
                newid = resarr[0]['@eid'];
            callback(msg + newid);
        } else if(qrytype==='U'){
            //let ret = 'I#' + entity + ' updated#Updated rows count: ' + results[1].changedRows;
            callback(msg);                      
        } else if(qrytype==='D'){
            //let resarr = results[1].affectedRows;
            callback(msg);
        }
    });

    connection.on('error', function (err) {
        connection.release();
        callback('E#connection.on-Error occurred.#'+ err.sqlMessage);   
        return;         
    });
});

}


0
投票

试试这个

var express = require('express');

var mysql     =    require('mysql');

var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');

var routes = require('./routes/index');
var users = require('./routes/users');

var app = express();

// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');

// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));

app.use('/', routes);
app.use('/users', users);

// catch 404 and forward to error handler
app.use(function(req, res, next) {
  var err = new Error('Not Found');
  err.status = 404;
  next(err);
});

// error handlers

// development error handler
// will print stacktrace
console.log(app);
if (app.get('env') === 'development') {
  app.use(function(err, req, res, next) {
    res.status(err.status || 500);
    res.render('error', {
      message: err.message,
      error: err
    });
  });
}

// production error handler
// no stacktraces leaked to user
app.use(function(err, req, res, next) {
  res.status(err.status || 500);
  res.render('error', {
    message: err.message,
    error: {}
  });
});

var con = mysql.createConnection({
  host: "localhost",
  user: "root",
  password: "admin123",
  database: "sitepoint"
});

con.connect(function(err){
  if(err){
    console.log('Error connecting to Db');
    return;
  }
  console.log('Connection established');
});



module.exports = app;

0
投票

您可以创建一个全局变量,然后在其他文件中访问该变量。

这是我的代码,我为 MySQL 数据库连接创建了一个名为 db.js 的单独文件

const mysql = require('mysql');

var conn = mysql.createConnection({
    host: "localhost",
    user: "root",
    password: "xxxxx",
    database: "test"
});

conn.connect((err) => {
    if (err) throw err;
    console.log('Connected to the MySql DB');
});

module.exports = conn;

然后在app.js文件中

const express = require('express');
const router = express.Router();

// MySql Db connection and set in globally
global.db = require('../config/db');

现在您可以在任何其他文件中使用它

const express = require('express');
const router = express.Router();

router.post('/signin', (req, res) => {
    try {
        var param = req.body;
        var sql = `select * from user`;

        // db is global variable
        db.query(sql, (err, data) => {
            if (err) throw new SyntaxError(err);
            res.status(200).json({ 'auth': true, 'data': data });
        });
    } catch (err) {
        res.status(400).json({ 'auth': false, 'data': err.message });
    }
});

0
投票

当您使用 mysql2 库在 Node.js 中设置 MySQL 连接池并将其导出为您创建的 database.js 文件时,连接池本身是相对于 Node.js 应用程序生命周期的单例。

© www.soinside.com 2019 - 2024. All rights reserved.