SQL Server和带有Sequelize的节点

我最近正在从事一个项目,该项目需要通过节点应用程序与 MSSQL 数据库进行交互。我涉水浏览互联网的深处,拼凑出我的解决方案,从各种不太满足我要求的解决方案中获取见解。经过一些挫折/疲惫的循环后,我的 Node API 现在正愉快地与我的 MSSQL 服务器交谈,我可以用我未来的自我(以及任何可能需要做类似事情的人)来解释我来的解决方案。   Zel码友部落

Zel码友部落
前言

在进入实现细节之前,了解我的一些约束进入项目可能很重要。首先,项目(此部分)的目标是使用 Node 连接到 SQL Server 数据库、创建用户表以及执行基本查找和插入,以奠定用户身份验证的基础。在我知道如何实现使用 Node 与数据库交互的目标之前,我知道我的基本技术堆栈将看起来像这样:Zel码友部落

  • 节点:Web API 后端
  • 快速:节点的 Web 框架
  • 护照:节点的身份验证中间件
  • MSSQL:数据库服务器

这些约束影响了我对于其他库和包所做的选择。节点的选择是因为我对 Javascript 的熟悉, 和 Express 和 Passport 被选中, 因为我有这些包的基本经验。默认情况下选择 MSSQL 作为数据库层(不是我选择)。Zel码友部落

在节点中与 SQL 交互

很快,SQL 和节点的使用速度与关系数据库(如 MongoDB 与 Node)的频繁使用速度非常之快。因此,关于该专题的文档/教程情况不同,而且普遍缺乏。在 npm 上发布了多个包,目的是在 Node 中连接 SQL 服务器和数据库并与之交互。我将明确表示,我选择库的主要优先事项是文档。在这个特定的项目中,要阅读库源代码来了解如何完成基本任务,这可不是利用我的时间。被带领下来的谷歌搜索兔子洞这个名单,我最终降落在乏味,因为它是由微软正式支持,似乎有体面的文件。我最终通过一个 Microsoft/Azure 代码示例找到了express4-繁琐,这似乎很有希望,但没有文档经过一个非常基本的用例。在浏览 github 时,我遇到一些调查结果,其中涉及使用 Node 与 SQL 服务器 (bingo) 交互的用户的输入。尽管总响应量相对较少,而且响应者明显被那些从某种意义上说已经受到乏味影响的人扭曲,但看看其他人是如何解决类似问题的是有帮助的。Zel码友部落

结果表明,乏味是最流行的驱动程序用于连接节点应用程序到SQL服务器,但我注意到一些响应,表明响应者使用乏味通过后遗症。Sequelize 是一个基于承诺的 OrM 节点,支持 mssql (除其他外), 其广泛的文档,甚至一些博客教程足以说服我.Zel码友部落

需要注意的是,续集用于 mssql 驱动程序,因此繁琐和续集一起使用:Zel码友部落

npm 安装乏味的续集Zel码友部落

连接到 SQL 服务器和数据库

好吧, 我仍然没有太多, 除了一个起点与乏味和续集。首先,我需要创建与 SQL 服务器的连接。首先,我在主应用程序、节点文件中创建了一个新的.js实例,并使用序列化身份验证方法测试了连接:Zel码友部落
 Zel码友部落

  const Sequelize = require('sequelize');
  const sequelize = new Sequelize('database', 'username', 'password', {
  host: 'SQL.server.address.database.net',
  dialect: 'mssql',
  dialectOptions: {
  encrypt: true;
  }
  });
   
  sequelize
  .authenticate()
  .then(() => {
  console.log('Connection has been established successfully.');
  })
  .catch(err => {
  console.error('Unable to connect to the database:', err);
  });
Zel码友部落
view rawapp.js hosted with ❤ by GitHub

 Zel码友部落

  const Sequelize = require('sequelize');
  const sequelize = new Sequelize('database', 'username', 'password', {
  host: 'SQL.server.address.database.net',
  dialect: 'mssql',
  dialectOptions: {
  encrypt: true;
  }
  });
   
  sequelize
  .authenticate()
  .then(() => {
  console.log('Connection has been established successfully.');
  })
  .catch(err => {
  console.error('Unable to connect to the database:', err);
  });
Zel码友部落
太酷了,现在我知道我可以连接到数据库了。 下一步是做一些有用的事情……Zel码友部落
Zel码友部落
创建模型Zel码友部落
Sequelize具有数据库模型的概念,我们可以在其中定义将要存储在数据库中的数据的形状。 这些模型对应于数据库中的表。 就我而言,我知道我需要一个用户表,因此我在项目中创建了一个models文件夹,并将user.js文件添加到该文件夹中。 在这里,我定义了用户模型(因此定义了用户表)。
  module.exports = function(sequelize, Sequelize) {
  const User = sequelize.define('user', {
  id: {
  autoIncrement: true,
  primaryKey: true,
  type: Sequelize.INTEGER
  },
  firstname: {
  type: Sequelize.STRING,
  notEmpty: true
  },
  lastname: {
  type: Sequelize.STRING,
  notEmpty: true
  },
  email: {
  type: Sequelize.STRING,
  unique: true,
  notEmpty: true,
  validate: {
  isEmail: true
  }
  },
  password: {
  type: Sequelize.STRING,
  allowNull: false
  },
  });
   
  return User;
  }
Zel码友部落
view rawuser.js hosted with ❤ by GitHub

 Zel码友部落

  module.exports = function(sequelize, Sequelize) {
  const User = sequelize.define('user', {
  id: {
  autoIncrement: true,
  primaryKey: true,
  type: Sequelize.INTEGER
  },
  firstname: {
  type: Sequelize.STRING,
  notEmpty: true
  },
  lastname: {
  type: Sequelize.STRING,
  notEmpty: true
  },
  email: {
  type: Sequelize.STRING,
  unique: true,
  notEmpty: true,
  validate: {
  isEmail: true
  }
  },
  password: {
  type: Sequelize.STRING,
  allowNull: false
  },
  });
   
  return User;
  }
Zel码友部落
由于最终我可能还会有其他模型以及用户,因此我需要一个地方将所有模型放在一起。 在models文件夹中,我制作了一个index.js文件来完成此操作。
  const fs = require('fs');
  const path = require('path');
  const Sequelize = require('sequelize');
  const config = require('../config/db');
   
  let db = {};
  let sequelize = new Sequelize(config.database, config.username, config.password, config.options);
   
  fs
  .readdirSync(__dirname)
  .filter(file => (file.indexOf(".") !== 0) && (file !== 'index.js'))
  .forEach(file => {
  let model = sequelize.import(path.join(__dirname, file));
  db[model.name] = model;
  });
   
  Object.keys(db).forEach(modelName => {
  if("associate" in db[modelName]) {
  db[modelName].associate(db);
  }
  });
   
  db.sequelize = sequelize;
  db.Sequelize = Sequelize;
   
  module.exports = db;
Zel码友部落
view rawindex.js hosted with ❤ by GitHub

 Zel码友部落

  const fs = require('fs');
  const path = require('path');
  const Sequelize = require('sequelize');
  const config = require('../config/db');
   
  let db = {};
  let sequelize = new Sequelize(config.database, config.username, config.password, config.options);
   
  fs
  .readdirSync(__dirname)
  .filter(file => (file.indexOf(".") !== 0) && (file !== 'index.js'))
  .forEach(file => {
  let model = sequelize.import(path.join(__dirname, file));
  db[model.name] = model;
  });
   
  Object.keys(db).forEach(modelName => {
  if("associate" in db[modelName]) {
  db[modelName].associate(db);
  }
  });
   
  db.sequelize = sequelize;
  db.Sequelize = Sequelize;
   
  module.exports = db;
Zel码友部落
我使用sequelize define方法以及sequelize类型来创建用户定义。 条目(电子邮件,密码等)将与数据库中用户表中的列相对应。 然后,我将models文件夹中的所有模型加载到models / index.js中的单个导出对象中。Zel码友部落
Zel码友部落
数据库同步Zel码友部落
所以现在我有Zel码友部落
Zel码友部落
两个已安装的软件包(序列化,乏味)Zel码友部落
使用sequelize进行测试连接Zel码友部落
用户模型Zel码友部落
但是,如果我查看我的数据库,它仍然是空的,那么我需要在数据库中创建用户表。 由于我具有模型结构,因此可以使用sync方法进行工作以进行后续处理。 此方法将同步数据库中尚未存在的所有模型(为它们创建表)。Zel码友部落
Zel码友部落
就我而言,我正在使用Express(特别是Express生成器)来设置我的Node应用程序,因此同步数据库的最佳位置是在服务器开始侦听其指定端口之前。 对于Express生成器,这发生在bin / www文件中:
  const models = require('../models');
   
  models.sequelize.sync().then(function() {
  server.listen(port);
  server.on('error', onError);
  server.on('listening', onListening);
  });
Zel码友部落
view rawwww hosted with ❤ by GitHub

 Zel码友部落

  const models = require('../models');
   
  models.sequelize.sync().then(function() {
  server.listen(port);
  server.on('error', onError);
  server.on('listening', onListening);
  });
Zel码友部落
现在,我可以通过从Node应用程序中任何位置导出的模型与数据库和表进行交互。Zel码友部落
Zel码友部落
查询数据库Zel码友部落
现在,我已经设置了模型并同步了数据库,现在可以通过导入模型来查询应用程序中任何位置的数据库表。 例如:Zel码友部落
 
  const models = require('../models');
   
  models.user.findOne({ where: {id: id} })
  .then(user => {
  // Do something with User instance
  });
   
  models.user.create(data)
  .then((newUser) => {
  // Do something with User instance
  });
Zel码友部落
view rawexample.js hosted with ❤ by GitHub

 Zel码友部落

  const models = require('../models');
   
  models.user.findOne({ where: {id: id} })
  .then(user => {
  // Do something with User instance
  });
   
  models.user.create(data)
  .then((newUser) => {
  // Do something with User instance
  });
Zel码友部落
findOne和create方法都由Sequelize库提供,并返回模型实例。Zel码友部落
Zel码友部落
我将在后续文章中详细介绍如何使用Node,Express,Passport,Sequelize和MSSQL实现身份验证。 但是现在,这是如何进行连接,建立表以及查询数据库的基本要点。Zel码友部落