var nodePort = 3030;
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
var db = require('mysql');
var dbPool = db.createPool({
host : 'localhost',
user : 'root',
password : '1234',
database : 'test',
port : 3306
});
app.use( bodyParser.json() );
app.get('/api/db', function(req, res){
res.setHeader('content-type', 'application/json');
dbPool.getConnection(function(objErr, objConn){
if(objErr){
sendError(res, 503, 'error', 'connection', objErr); //503 - Service Unavailable
}else{
objConn.query("SELECT * FROM person", function(Err, Rows, Fields){
if(Err){
sendError(res, 500, 'error', 'query', Err);
}else{
res.send({
results : 'success',
err : '',
err_type : '',
fields : Fields,
rows : Rows,
length : Rows.length
});
objConn.release();
}//else
});
}//else
});
});
/*
app.get('/api/db:id', function(req, res){
var id = req.params.id;
res.setHeader('content-type', 'application/json');
dbPool.getConnection(function(objErr, objConn){
if(objErr){
sendError(res, 503, 'error', 'connection', objErr); //503 - Service Unavailable
}else{
objConn.query("SELECT * FROM person WHERE id = ? ",[id], function(Err, Rows, Fields){
if(Err){
sendError(res, 500, 'error', 'query', Err);
}else{
res.send({
results : 'success',
err : '',
err_type : '',
fields : Fields,
rows : Rows,
length : Rows.length
});
objConn.release();
}//else
});
}//else
});
});
*/
app.post('/api/db', function(req, res){
if(!req.body.tableName){
var data = {
ID : req.body.id,
Name : req.body.name
}
tableName = 'person';
}else{
var data = {
email : req.body.email,
regid : req.body.regid
}
tableName = 'users';
}//else
console.log(req.body.regid);
console.log(req.body.tableName);
console.log(req.body.email);
res.setHeader('content-type', 'application/json');
dbPool.getConnection(function(objErr, objConn){
if(objErr){
sendError(res, 503, 'error', 'connection', objErr); //503 - Service Unavailable
}else{
objConn.query("INSERT INTO "+tableName+" SET ? ", data, function(Err, Rows, Fields){
if(Err){
sendError(res, 500, 'error', 'query', Err);
}else{
res.send({
results : 'success'
});
objConn.release();
if(!req.body.tableName){ gcmSend(); }
}//else
});
}//else
});
});
app.put('/api/db', function(req, res){
var id = req.body.id;
var data = {
Name : req.body.name
}
res.setHeader('content-type', 'application/json');
dbPool.getConnection(function(objErr, objConn){
if(objErr){
sendError(res, 503, 'error', 'connection', objErr); //503 - Service Unavailable
}else{
objConn.query("UPDATE person SET ? WHERE ID = ? ", [data,id], function(Err, Rows, Fields){
if(Err){
sendError(res, 500, 'error', 'query', Err);
}else{
res.send({
results : 'success'
});
objConn.release();
gcmSend();
}//else
});
}//else
});
});
app.delete('/api/db/:id', function(req, res){
var id = req.params.id;
res.setHeader('content-type', 'application/json');
dbPool.getConnection(function(objErr, objConn){
if(objErr){
sendError(res, 503, 'error', 'connection', objErr); //503 - Service Unavailable
}else{
objConn.query("DELETE FROM person WHERE ID = ? ",[id], function(Err, Rows, Fields){
if(Err){
sendError(res, 500, 'error', 'query', Err);
}else{
res.send({
results : 'success'
});
objConn.release();
gcmSend();
}//else
});
}//else
});
});
function gcmSend(){
message = new gcm.Message({
collapseKey: 'demo',
delayWhileIdle: true,
timeToLive: 3,
data: {
title: 'Node.js den mesaj gönderildi'
}
});
sender.send(message, registrationIds, 4, function (err, result) {
console.log(result);
});
}
function sendError(res, iStatusCode, strResult, strType, objError){
res.send({
results : strResult,
err : objError.type,
err_type : strType
});
}
app.listen(nodePort);
console.log('App listening on port' + nodePort);
你好,
我写了一些代码来与nodejs mysql连接,我打开了每个操作的新连接(post,get,put,delete)并发布。这很好吗?还是一种连接更好?一个连接中的所有操作或每个操作一个连接中的所有操作之间有什么区别?
最佳答案
需要说明的是-Node.js是而不是单线程。您的应用程序代码是在一个线程中执行的,但是在后台它会在需要时使用它们-看一看here(答案和下面的注释):
和:
如您所见,您使用的mysql
模块要求您传递query()
方法的回调(可能还有更多)。因此,当您调用它时,将继续执行代码,并在数据库结果到达时调用回调。
至于您的问题-您不是在为每个请求创建新的连接。看一看mysql
模块的自述文件Pooling Connections section:
当您调用dbPool.getConnection()
时,仅在池中没有可用连接的情况下才会创建连接-否则,它只会从其顶部抓取一个连接。调用objConn.release()
会将连接释放回池-它没有断开连接。此调用使它可以被应用程序的其他部分重用。
总结一下:
更新:
要回答评论中的问题:
当您对每个请求使用一个连接时,
mysql
模块必须打开一个新的套接字,连接数据库并在进行查询之前进行身份验证-这会花费时间并占用一些资源。因此,这是一个不好的方法。另一方面,当仅使用一个连接(而不是连接池)时,运行需要很长时间才能完成的查询将阻塞该连接上的所有其他查询,直到连接完成为止-这意味着任何其他请求都必须等待。这也是一个不好的方法。
为每个请求创建一个新的连接池几乎就像使用新的连接一样,除非您多次调用
pool.getConnection()
,否则甚至更糟(获取创建新连接所用的资源,并乘以pool.getConnection()
调用的次数)。为了进一步阐明每个操作的一个连接与一个连接问题中的所有操作:
每个连接中的每个操作都在上一个操作完成之后开始(它是同步的,但不是在客户端),因此,如果您的表有几十亿行并发出
SELECT * FROM yourtable
,将需要一些时间来完成,从而阻塞了此连接直到完成。如果您需要并行执行的每个操作都具有一个连接(例如,对于每个请求),问题将消失。但是如前所述,打开新连接需要时间和资源,这就是引入连接池概念的原因。
因此答案是:对所有请求使用一个连接池(就像您在示例代码中所做的一样)-连接的数量将根据应用程序的流量进行相应调整。
更新#2:
基于这些评论,我看到我也应该解释连接池背后的概念。它的工作方式是在连接池为空的情况下启动应用程序,并初始化为最多创建n个连接(默认情况下,
mysql
模块的连接数为10)。每当您调用
dbPool.getConnection()
时,它都会检查池中是否有任何可用的连接。如果有,它会捕获一个(使其不可用),否则,它将创建一个新的。如果达到连接限制并且没有可用的连接,则会引发某种异常。调用
connection.release()
会将连接释放回池,以便再次可用。使用池仅为整个应用程序获得一个全局连接是完全错误的,并且违反了概念本身(您可以通过手动创建连接来完成相同的操作),因此使用连接池意味着将连接池用作它应该被使用-当您需要它们时从它获取连接。
关于javascript - Node js(getConnection),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/26118700/