2016-09-02 3 views
0

Ich machte node.js App, die einige REST-Dienste enthält. Diese Dienste stellen eine Verbindung zu einer Datenbank her (z. B. Oracle oder DB2), um bestimmte Abfragen auszuführen.Knoten js Datenbankverbindung in einem separaten Modul

Da ich ein Anfänger in node.js Programmierung bin, habe ich eine Frage zu meinem Fall: Was ist der richtige Weg, um auf eine Datenbank zuzugreifen? Ist es besser, eine Verbindungsreferenz zu haben, während die App läuft, und dieselbe Verbindungsinstanz zu verwenden, wenn REST-Dienste aufgerufen werden?

fand ich einige Beispiele, die Datenbankverbindung in einem separaten Modul enthält und das Modul in App verwenden, so ähnlich:

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

Wenn dieser Service aufgerufen wird, lautet db2connectionundefined. Woher? Wie sollte ich eine db2-Verbindung von db2.js Datei abrufen?

+0

Das Problem ist, dass Ihre Datenbankverbindung asynchron eingerichtet ist. Sie erhalten die eigentliche Verbindung als 'conn'-Parameter im Callback und nicht als synchronen Rückgabewert von' .open() '. – Sirko

+0

Ich bin nicht vertraut mit 'ibm_db', aber ich würde ein paar grundlegende Debugging vorschlagen, um herauszufinden, was los ist. Fügen Sie einige 'console.log's zu verschiedenen Stellen hinzu, wie in db2.js, um zu sehen, ob es an erster Stelle geladen ist, und melden Sie sich dann dbConn ab, um zu sehen, ob' db2.open' einen Wert zurückgegeben hat. – Whothehellisthat

+0

@Whothehellisthat ich schon das getan und es ist 'undefiniert' auch in' db2.js'. Ich glaube also, dass es wirklich etwas mit Callback zu tun hat, aber ich kann es nicht wirklich in der Datei 'server.js' arbeiten lassen. – peterremec

Antwort

2

Wie gesagt von @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

Ich bin mir nicht sicher, ob die Lösung so einfach ist, da hier bei jedem Aufruf der Funktion eine neue Datenbankverbindung aufgebaut wird. Je nach dem Rest des Codes können Sie also mit LOTS von Verbindungen enden. – Sirko

+0

Fair genug. Ich habe es mit einem einfachen Versprechen-ähnlichen System aktualisiert. – Whothehellisthat

+0

@Whothehellisthat danke, es hat funktioniert. Würden Sie etwas Kommentar zu diesem Code hinzufügen? Ich würde gerne verstehen, was es tut ... – peterremec

2

Für Oracle with node-oracledb es einfach ist, zu erstellen und einen Verbindungspool zu verwenden. Ihre Anwendung würde nur dann eine freie Verbindung aus dem Pool erhalten, wenn sie eine HTTP-REST-Anforderung verarbeitet. Schauen Sie sich webapp.js und webapppromises.js in der examples. Node-oracledb hat eine "Verbindungspool-Warteschlange" (siehe doc), die Verbindungslastspitzen behandelt. Es hat auch einen "Verbindungspool-Cache" (siehe auch das Dokument), mit dem Sie einfach auf einen Pool zugreifen können, der in einem anderen Modul erstellt wurde.

+0

Ich denke, wenn eine App innerhalb kurzer Zeit nur wenige Verbindungen nutzt, muss kein Verbindungspool erstellt werden, oder? Was ist der häufigste Ansatz in diesem Fall? Wenn ich über mehrere REST-Dienste mit Datenbankzugriff verfüge, sollte ich bei jedem Aufruf eines Dienstes eine neue Verbindung erstellen oder sollte ich dieselbe Verbindungsreferenz verwenden? – peterremec

+1

würde ich wahrscheinlich mit einem kleinen Pool gehen. –

+0

Danke für einen Vorschlag! – peterremec

Verwandte Themen