使用node-mysql同时进行查询

时间:2014-03-27 16:51:47

标签: javascript mysql node.js connection-pooling node-mysql

我有一个查询MySQL表的Javascript程序,我无法弄清楚为什么同步查询的结果处理得不好。

对象有多个实例,区域。在实例化对象时,我查询数据库以获取一些信息。

我的问题是,当我同时实例化两个对象时,第一个查询的结果写在第二个对象中。

我尝试使用池创建两个不同的连接,但它不会改变任何内容。

这是我的代码:

Getter into database:

getOrdresAchat = function(aConnection, aIdZone, aCallback){
    aConnection.query("SELECT * FROM Ordre WHERE Entreprise_idEntreprise = "+aIdZone+" AND Sens = 'Achat' ORDER BY Valeur DESC;", aCallback); 
}

对象定义:

//No need to check that object
Ordre = function(aNumero, aJoueur, aEntreprise, aSens, aTypeOrdre, aQuantite, aPrix, aBorneInf, aBorneSup) {
    this.numero = aNumero;
    this.entreprise = aEntreprise;
    this.joueur = aJoueur;
    this.sens = aSens;
    this.typeOrdre = aTypeOrdre; // 'cours_limite', 'meilleure_limite', 'seuil_declenchement' ou 'au_marche'
    this.quantite = aQuantite; // nombre entier positif
    this.prix = aPrix; //si le prix est nul il est considéré comme sans limite
    this.borneInf = aBorneInf;
    this.borneSup = aBorneSup; 
}

//kinda an array of Ordre
Carnet_achat = function() { 
    this.liste = [];
    this.addElement = function(aOrdre) {
        this.liste.push(aOrdre);
    };

    this.display= function(){
        console.log("begining carnet_achat.display | List.length : "+this.liste.length);
        for(i in this.liste){
            console.log("row "+i+" : " +this.liste[i].prix);
        }
    };

}

Zone = function(aIdZone, aConnection) {
    var idZone = aIdZone;

    this.setIdZone = function(aNewId){
        idZone = aNewId;
    }

    this.getIdZone =function(){
        return idZone;
    }

    this.getCarnetAchat = function(aConnection){
        rCarnet_achat = new Carnet_achat(); //rCarnet is temporary object

        //we query database and push every row into the temp object
        getOrdresAchat(aConnection, idZone, function(err, rows){
            if(err) throw err;
            for(i in rows){
                ordreToAdd = new Ordre(rows[i].idOrdre, 
                                        rows[i].Joueur_idJoueur, 
                                        rows[i].Entreprise_idEntreprise, 
                                        rows[i].Sens, 
                                        rows[i].Type, 
                                        rows[i].Quantite, 
                                        rows[i].Valeur,
                                        rows[i].BorneInf,
                                        rows[i].BorneSup);
                rCarnet_achat.addElement(ordreToAdd);
            }
        });
        return rCarnet_achat;
    }

    //init
    this.carnet_achat = new this.getCarnetAchat(aConnection);

}

主要:

var mysql = require('mysql');
var pool = mysql.createPool({
    host     : 'localhost', 
    user     : 'Bibacoeur', 
    password : 'Bibacoeur2014', 
    database : 'bibacoeur'
});

pool.getConnection(function(err, connectionA) {
    if(err) throw err;
    GI = new Zone(1, connectionA); //connection is used to query database

    //timeOut to wait the end of the query
    setTimeout(function(){console.log("GI_ACHAT");GI.carnet_achat.display();},3000);

});

pool.getConnection(function(err, connectionB) {
    if(err) throw err;
    GE = new Zone(2, connectionB); //connection is used to query database

        //timeOut to wait the end of the query
    setTimeout(function(){console.log("GE_ACHAT");GE.carnet_achat.display();},3000);

});

数据库:

mysql> select Entreprise_idEntreprise, Sens, Valeur from ordre;
+-------------------------+-------+--------+
| Entreprise_idEntreprise | Sens  | Valeur |
+-------------------------+-------+--------+
|                       1 | Vente |      0 |
|                       1 | Vente |  90000 |
|                       1 | Vente |  91000 |
|                       1 | Vente |  92000 |
|                       1 | Vente |  95000 |
|                       1 | Vente | 100000 |
|                       1 | Achat |  88500 |
|                       1 | Achat |  90500 |
|                       1 | Achat |  90500 |
|                       2 | Achat |      0 |
+-------------------------+-------+--------+
10 rows in set (0.00 sec)

结果日志:

C:\Users\QuentinB\Google Drive\Desktop\temp>node app.js
GI_ACHAT
begining carnet_achat.display | List.length : 0
GE_ACHAT
begining carnet_achat.display | List.length : 4
row 0 : 90500
row 1 : 90500
row 2 : 88500
row 3 : 0

应该是:

C:\Users\QuentinB\Google Drive\Desktop\temp>node app.js
GI_ACHAT
begining carnet_achat.display | List.length : 3
row 0 : 90500
row 1 : 90500
row 2 : 88500
GE_ACHAT
begining carnet_achat.display | List.length : 1
row 0 : 0

似乎第一个对象GI完成的查询结果是由第二个对象GE接收的。

我试图用setTimeout(function(){GE = new Zone(2, connectionB);},10);来延迟第二个对象的创建,并且它有效。 但是我不想延迟每一次创作,因为我还有40个物体可以实现。

如果我想确定正确的对象收到我的查询结果,我该怎么办?

感谢阅读!

1 个答案:

答案 0 :(得分:0)

由于您未使用rCarnet_achat关键字声明var,因此您隐式将其声明为全局变量。因此,每次调用rCarnet_achat.addElement(ordreToAdd);时,您实际上都会向相同的 Carnet_achat实例添加元素。可以通过将var rCarnet_achat;添加到Zone函数的顶部来解决此问题。

P.S。你的代码充满了其他问题,例如

  • 您应该使用node-mysql的查询字符串转义来避免SQL注入攻击,例如aConnection.query("SELECT * FROM Ordre WHERE Entreprise_idEntreprise = ? AND Sens = 'Achat' ORDER BY Valeur DESC;", aIdZone, aCallback)
  • 使用setTimeout等待SQL查询完成是错误的。等待回调。
  • 由于你有“另外40个对象需要实例化”,你可以考虑编写一个查询来同时获取所有对象,例如: select * from foo where id in (1,2,3);