我正在试图弄清楚如何构建我的应用程序以使用MySQL最有效的方式.我正在使用node-mysql模块.这里的其他线程建议使用连接池,所以我设置了一个小模块mysql.js
var mysql = require('mysql');
var pool = mysql.createPool({
host : 'localhost',
user : 'root',
password : 'root',
database : 'guess'
});
exports.pool = pool;
Run Code Online (Sandbox Code Playgroud)
现在每当我想查询mysql时,我需要这个模块,然后查询数据库
var mysql = require('../db/mysql').pool;
var test = function(req, res) {
mysql.getConnection(function(err, conn){
conn.query("select * from users", function(err, rows) {
res.json(rows);
})
})
}
Run Code Online (Sandbox Code Playgroud)
这是好方法吗?我真的找不到太多使用mysql连接的例子,除了非常简单的例子,其中一切都在主app.js脚本中完成,所以我真的不知道什么是约定/最佳实践.
我应该在每次查询后总是使用connection.end()吗?如果我在某个地方忘了怎么办?
如何重写我的mysql模块的导出部分只返回一个连接,所以我不必每次都写getConnection()?
Kla*_*aak 52
这是一个很好的方法.
如果您只想获得连接,请将以下代码添加到池所在的模块中:
var getConnection = function(callback) {
pool.getConnection(function(err, connection) {
callback(err, connection);
});
};
module.exports = getConnection;
Run Code Online (Sandbox Code Playgroud)
你仍然必须每次都写getConnection.但是你可以在第一次获得它时保存模块中的连接.
完成使用后不要忘记结束连接:
connection.release();
Run Code Online (Sandbox Code Playgroud)
小智 13
你会发现这个包装有用:)
var pool = mysql.createPool(config.db);
exports.connection = {
query: function () {
var queryArgs = Array.prototype.slice.call(arguments),
events = [],
eventNameIndex = {};
pool.getConnection(function (err, conn) {
if (err) {
if (eventNameIndex.error) {
eventNameIndex.error();
}
}
if (conn) {
var q = conn.query.apply(conn, queryArgs);
q.on('end', function () {
conn.release();
});
events.forEach(function (args) {
q.on.apply(q, args);
});
}
});
return {
on: function (eventName, callback) {
events.push(Array.prototype.slice.call(arguments));
eventNameIndex[eventName] = callback;
return this;
}
};
}
};
Run Code Online (Sandbox Code Playgroud)
需要它,像这样使用它:
db.connection.query("SELECT * FROM `table` WHERE `id` = ? ", row_id)
.on('result', function (row) {
setData(row);
})
.on('error', function (err) {
callback({error: true, err: err});
});
Run Code Online (Sandbox Code Playgroud)
bin*_*nki 10
pool.getConnection()如果可以,应避免使用。如果您致电pool.getConnection(),则必须connection.release()在使用完连接后致电。否则,一旦达到连接限制,您的应用程序将永远陷入等待连接返回到池的状态。
对于简单查询,可以使用pool.query()。connection.release()即使在错误情况下,该速记也会自动为您服务。
function doSomething(cb) {
pool.query('SELECT 2*2 "value"', (ex, rows) => {
if (ex) {
cb(ex);
} else {
cb(null, rows[0].value);
}
});
}
Run Code Online (Sandbox Code Playgroud)
但是,在某些情况下,您必须使用pool.getConnection()。这些情况包括:
如果必须使用pool.getConnection(),请确保connection.release()使用类似于以下的模式进行调用:
function doSomething(cb) {
pool.getConnection((ex, connection) => {
if (ex) {
cb(ex);
} else {
// Ensure that any call to cb releases the connection
// by wrapping it.
cb = (cb => {
return function () {
connection.release();
cb.apply(this, arguments);
};
})(cb);
connection.beginTransaction(ex => {
if (ex) {
cb(ex);
} else {
connection.query('INSERT INTO table1 ("value") VALUES (\'my value\');', ex => {
if (ex) {
cb(ex);
} else {
connection.query('INSERT INTO table2 ("value") VALUES (\'my other value\')', ex => {
if (ex) {
cb(ex);
} else {
connection.commit(ex => {
cb(ex);
});
}
});
}
});
}
});
}
});
}
Run Code Online (Sandbox Code Playgroud)
我个人更喜欢使用Promises和useAsync()模式。与async/ 结合使用的这种模式await使意外忘记release()连接变得更加困难,因为它将词法作用域转换为对以下内容的自动调用.release():
async function usePooledConnectionAsync(actionAsync) {
const connection = await new Promise((resolve, reject) => {
pool.getConnection((ex, connection) => {
if (ex) {
reject(ex);
} else {
resolve(connection);
}
});
});
try {
return await actionAsync(connection);
} finally {
connection.release();
}
}
async function doSomethingElse() {
// Usage example:
const result = await usePooledConnectionAsync(async connection => {
const rows = await new Promise((resolve, reject) => {
connection.query('SELECT 2*4 "value"', (ex, rows) => {
if (ex) {
reject(ex);
} else {
resolve(rows);
}
});
});
return rows[0].value;
});
console.log(`result=${result}`);
}
Run Code Online (Sandbox Code Playgroud)
我正在使用这个与mysql的基类连接:
"base.js"
var mysql = require("mysql");
var pool = mysql.createPool({
connectionLimit : 10,
host: Config.appSettings().database.host,
user: Config.appSettings().database.username,
password: Config.appSettings().database.password,
database: Config.appSettings().database.database
});
var DB = (function () {
function _query(query, params, callback) {
pool.getConnection(function (err, connection) {
if (err) {
connection.release();
callback(null, err);
throw err;
}
connection.query(query, params, function (err, rows) {
connection.release();
if (!err) {
callback(rows);
}
else {
callback(null, err);
}
});
connection.on('error', function (err) {
connection.release();
callback(null, err);
throw err;
});
});
};
return {
query: _query
};
})();
module.exports = DB;
Run Code Online (Sandbox Code Playgroud)
就这样使用它:
var DB = require('../dal/base.js');
DB.query("select * from tasks", null, function (data, error) {
callback(data, error);
});
Run Code Online (Sandbox Code Playgroud)