2016-09-02 74 views
0

我製作了包含一些REST服務的node.js應用程序。這些服務連接到數據庫(例如Oracle或DB2)以執行某些查詢。單獨模塊中的節點js數據庫連接

因爲我是node.js編程的初學者,所以我有一個關於我的情況的問題: 什麼是訪問數據庫的正確方法?在應用程序運行時擁有一個連接引用並在調用REST服務時使用相同的連接實例會更好嗎?

我發現了一些例子,包括在一個單獨的模塊,數據庫連接,並使用該模塊中的應用,這樣的事情:

db2.js:

var db2 = require('ibm_db'); 

var db2ConnSettings = "DRIVER={DB2};DATABASE=mydb;HOSTNAME=localhost;UID=db2test;PWD=db2test;PORT=50000;PROTOCOL=TCPIP"; 

var db2Conn = db2.open(db2ConnSettings, function(err, conn) { 
     if (err) 
      return console.log(err); 
    }); 

module.exports = db2Conn; 

server.js:

var express = require('express'); 
var app = express(); 
var db2Connection = require('./db2.js'); 

app.get('/data', function(req, res) { 
    console.log(db2Connection); 
    // make some query 
}); 

當調用此服務時,db2connectionundefined。怎麼來的?我應該如何從db2.js文件檢索db2連接?

+0

問題是,您的數據庫連接是異步設置的。你在回調中將實際的連接作爲'conn'參數,而不是'.open()'的同步返回值。 – Sirko

+0

我對'ibm_db'不熟悉,但是我會建議進行一些基本的調試來弄清楚發生了什麼。將一些'console.log'添加到不同的地方,比如在db2.js中查看它是否被加載,然後註銷dbConn以查看'db2.open'是否返回值。 – Whothehellisthat

+0

@Whathehellist我已經這樣做了,它也是'db2.js'中的'undefined'。所以我相信它確實與回調有關,但我無法真正使它在'server.js'文件中工作。 – peterremec

回答

2

正如@Sirko說:

db2.js

var db2 = require('ibm_db'); 
var db2ConnSettings = "DRIVER={DB2};DATABASE=mydb;HOSTNAME=localhost;UID=db2test;PWD=db2test;PORT=50000;PROTOCOL=TCPIP"; 

var err, conn; 
var callbacks = []; 

module.exports = function(callback) { 
    // db2 module is called 

    if (err || conn) { 
    // connection has already been established 
    // (results of db2.open have been stored) 
    // callback immediately 
    callback(err, conn); 
    } 
    else { 
    // connection has not been established 
    // store the callback for when db connects 
    callbacks.push(callback); 
    } 
}; 

db2.open(db2ConnSettings, function(_err, _conn){ 
    // db has connected 

    err = _err; conn = _conn; // store results 
    var next_callback; 

    // array.pop() removed the last item from the array 
    // and returns it. if no items are left, returns null. 
    // so this loops through all stored callbacks. 
    while(next_callback = callbacks.pop()) { 
    // the removed item is stored in next_callback 
    next_callback(err, conn); // send connection results to callback 
    } 

    // no more items in callbacks to trigger 
}); 

server.js

var express = require('express'); 
var app = express(); 
var db2Connection = require('./db2.js')(function(err, conn) { 
    // triggered if the connection has already been established 
    // or as soon as it HAS been established 
    app.get('/data', function(req, res) { 
     console.log(conn); 
     // ... 
    }); 
}); 
+0

我不確定,如果解決方法如此簡單,每次函數被調用時都建立一個新的數據庫連接。因此,根據代碼的其餘部分,最終可能會有很多連接。 – Sirko

+0

夠公平的。我用一個簡單的承諾類系統更新了它。 – Whothehellisthat

+0

@Whathehellisthat謝謝,它工作。您介意在該代碼中添加一些評論嗎?我想了解它是什麼... – peterremec

2

對於Oracle with node-oracledb它是簡單的創建和使用連接池。處理HTTP REST請求時,您的應用只會從池中獲得免費連接。請看examples中的webapp.jswebapppromises.js。 Node-oracledb具有處理連接負載尖峯的'連接池隊列'(參見doc)。它還有一個'連接池緩存'(也參見文檔),可以很容易地訪問在不同模塊中創建的池。

+0

我想如果一個應用程序在短時間內只使用幾個連接,就不需要創建連接池了,對吧?那種情況下最常用的方法是什麼?如果我有多個具有數據庫訪問權限的REST服務,每次調用服務時應該創建一個新連接還是應該使用相同的連接引用? – peterremec

+1

我可能會去一個小池。 –

+0

感謝您的建議! – peterremec