首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在nodejs中执行多个可靠的mysql查询

在nodejs中执行多个可靠的mysql查询
EN

Stack Overflow用户
提问于 2016-09-11 18:20:24
回答 2查看 2.4K关注 0票数 2

我正在处理一个项目,在该项目中我必须为用户创建团队,但在此之前,我需要检查团队名称是否已经被相同的user.Below占用,这是示例代码

代码语言:javascript
复制
 var mysql=require('../../config/mysql_connect.js');
 var dateFormat = require('dateformat');

 var functions={

    createTeam:function(data,cb){

        this.checkifExists(data,function(err,result){

            if(err)
            {
                cb(err);
            }
            else
            {
                if(result.length)
                {
                    cb(null,0); // Team name exists 
                }
                else
                {
                    mysql.getConnectionFromPool(function(err,con){

                        if(err)
                        {
                            cb(err);
                        }
                        else
                        {

                            var query=con.query("Insert into team SET ? ",data,function(err,result){

                            if(err)
                            {
                                cb(err);
                            }
                            else
                            {
                                cb(null,result.insertId);
                            }

                                con.release();
                            });

                           }
                        });
                }
            }
        });


    },
    checkifExists:function(data,cb){

        mysql.getConnectionFromPool(function(err,con){

            if(err)
            {
                cb(err);
            }
            else
            {
                var sql="Select id from team where user_id = ? and team_name like  "+ con.escape('%'+data.team_name+'%') ;  

                var query=con.query(sql,[data.user_id,data.team_name],function(err,result){

                    if(err)
                    {
                        cb(err);
                    }
                    else
                    {
                      cb(null,result);
                    }
                     con.release();
                });

                console.log(query.sql);
            }

        });
    }
};

module.exports=functions;

一切都很好,但是有没有更简单的方法来以更易管理的方式编写这种可靠的查询,因为有时会有超过3-4个查询,代码变得复杂和难以管理。

我知道同样的事情也可以通过mysql唯一索引来实现,但是如果有超过3-4个查询,并且在某些情况下索引不能满足我的需求,该怎么办

EN

回答 2

Stack Overflow用户

发布于 2016-09-11 22:13:53

正如我所看到的,有两个问题。

  1. 您不能将事务与非托管池连接一起使用,因为为一个连接启动的事务无法传递给其他连接。
  2. 您可以为每个函数获取和释放连接。这是不必要的重复代码。

要解决这些问题,你可以通过实体使用单独的连接,例如,一个连接用于team,第二个用于user等等。为了避免地狱回调,请使用async模块或promises。

这是草稿

代码语言:javascript
复制
// db.js
var mysql=require('../../config/mysql_connect.js');
var connections = {};

// No, that code don't solve problems, because transaction can't started inside other.
// Block mechanism by transaction property `is_busy` seems a bulky.
function DB(name) {
    if (!name)
        // unnamed connection. Must be released on query end.
        return mysql.getConnectionFromPool(); 

    if (!connections[name])
        // create always open connection
        connections[name] = mysql.getConnectionFromPool();

    return connections[name];
}

module.exports = DB;

// team.js
var dateFormat = require('dateformat');
var async = require('async');
var db = require('db')('team'); // get always-open connection for team-entity from pool

function create (data, cb) {
    // Here async is not necessary but used as example
    async.waterfall([
        function(cb) {
            isExists(data.user_id, data.team_name, cb);
        },  

        function(isTeamExists, cb) {
            if (!isTeamExists)
                return cb(); // go to end of waterfall
            // is a bad statement; use enum of fields
            db.query('insert into team SET ?', data, cb); 
        }],

        // end waterfall chain
        function(err, team_id) {
            if (err)
                return cb(err); // pass error to original cb-func

            ...do-smth and call cb without error... 
        }
    );  
}

function isExists (user_id, team_name, cb) {
    // You can use ?? to masked input
    db.query('select 1 from team where user_id = ?? and team_name like "%??%"', 
        [user_id, team_name], 
        function(err, res) {
            cb(err, !err && res.length > 0);
        }
    );
}

module.exports = {
    create,
    isExists
};
票数 1
EN

Stack Overflow用户

发布于 2016-09-12 11:26:06

这是每个人在使用JavaScript时遇到的基本问题。多年来,我尝试了许多不同的方法来解决这个问题。

在尝试了许多选项之后,我认为最好的方法(目前被广泛接受)是使用带有async/await关键字的babel。如果您使用es2017预设,这是确保其可用的一种方法。

现在的免责声明是,你仍然必须学习承诺。如果您试图跳过对async/await的承诺,您很快就会发现一堆基于承诺的代码毫无意义。另外,async/await需要promises..so,你需要自学。这需要一点时间来适应它。

通常对JavaScript有帮助的另一件事是使用两个空格,而不是四个或一个制表符。这确实会使您的代码更具可读性。此外,将左大括号放在同一行上,不要在各处添加额外的空行,只在使代码更容易阅读的地方添加空行。

因此,这不是确切的代码,而是我将如何做到这一点的大纲:

代码语言:javascript
复制
async function existsTeam(data) {
  const id = await query('select id ..', data);
  return id;
}

async function createTeam(data) {
  const existingId = await existsTeam(data);
  if (existingId) return existingId;

  const result = await query('insert into team ..', data);
  return result.insertId;
}

对于MySQL的特定情况,您正在尝试强制执行一个约束,我认为MySQL不支持数据库上的外键约束--但是您可以仔细检查,因为如果它支持外键约束,可能会简化事情。但这些类型的查询/更新可能更容易使用序列化或书架ORM。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39435056

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档