Node.JS使用Sequelize操作MySQL的示例代码


Posted in Javascript onOctober 09, 2017

Node.JS提供了操作数据库的基础接口,我们可以通过mysql模块的query方法进行操作,但是需要编写SQL语句,对于SQL语句并不精通的人来说有一定的难度,而且在代码中保留SQL语句也有一定的危险性。为了方便进行数据库操作,ORM框架应运而生,Sequelize正是这样的模块。

安装Sequelize

首先,使用cd命令将终端控制台定位到项目的根目录,然后使用npm安装:

npm install sequelize --save

安装mysql2

由于sequelize依赖于mysql2所以也需要安装mysql2:

npm install mysql2 --save

编写配置

在项目根目录新建个“configs”文件夹,在文件夹中新建一个名为“mysql-config.js”的文件,代码如下:

var config = {
  dbname: 'testdb',
  uname: 'root',
  upwd: 'root',
  host: 'localhost',
  port: 3306,
  dialect: 'mysql',
  pool: {
    max: 5,
    min: 0,
    idle: 10000
  }
};

module.exports = config;

配置说明

  • dbname: 数据库名称
  • uname: 数据库登录名
  • upwd: 数据库登录密码
  • host: 数据库主机
  • port: 数据库端口,mysql默认是3306
  • dialect: 数据库类型,这里是mysql
  • pool: 连接池配置

【具体配置详见MySQL相关的博客】

对sequelize进行简单封装

在项目根目录新建“data”文件夹,在改文件夹中新建“db.js”文件。在db.js中添加以下代码。

首先,创建sequelize实例:

// 引入模块
const Sequelize = require('sequelize');
// 读取配置
const mysqlConfig = require('../configs/mysql-config');

// 根据配置实例化seq
var seq = new Sequelize(mysqlConfig.dbname, mysqlConfig.uname, mysqlConfig.upwd, {
  host: mysqlConfig.host,
  dialect: mysqlConfig.dialect,
  pool: mysqlConfig.pool
});

定义一个defineModel函数用于定义数据模型:

/**
 * 定义数据模型
 * 
 * @param {any} name 模型名称【数据库表名】
 * @param {any} attributes 数据字段集合
 * @returns 数据模型对象
 */
function defineModel (name, attributes) {
  var attrs = {};

  for (let key in attributes) {
    let value = attributes[key];
    if (typeof value === 'object' && value['type']) {
      value.allowNull = value.allowNull || false;
      attrs[key] = value;
    } else {
      attrs[key] = {
        type: value,
        allowNull: false
      };
    }
  }

  // 附加公共字段
  // attrs.id = {
  //   type: ID_TYPE,
  //   primaryKey: true
  // };
  attrs.createAt = {
    type: Sequelize.BIGINT,
    allowNull: false
  };
  attrs.updateAt = {
    type: Sequelize.BIGINT,
    allowNull: false
  };
  attrs.version = {
    type: Sequelize.BIGINT,
    allowNull: false
  };
  // 状态:0表示有效,1表示无效,2表示已删除,默认为0.
  attrs.status = {
    type: Sequelize.INTEGER,
    allowNull: false
  };
  
   // 调用seq的方法定义模型并返回
  return seq.define(name, attrs, {
    tableName: name,
    timestamps: false,
    hooks: {
      beforeValidate: function (obj) {
        let now = Date.now();
        if (obj.isNewRecord) {
          obj.createAt = now;
          obj.updateAt = now;
          obj.version = 0;
        } else {
          obj.updateAt = now;
          ++obj.version;
        }
      }
    }
  });
}

在这里我们可以对模型定义做一些修改,比如添加id、createAt、updateAt、version和status字段等。这样,通过这个函数定义的模型都会带这几个字段,通常一个数据库表都应该包含这些字段。

sequelize默认会为模型添加id字段,自增,主键。所以在这里可以不用关心该字段的定义。

在调用seq.define()方法的时候,设置了“timestamps”为false,当timestamps为true时,默认会为模型添加createAt和updateAt两个字段,数据类型为Sequelize.DATE,这里我们自己定义为Sequelize.BIGINT用于存储时间戳。

同时,设置tableName和模型的名称一致,这样符合我们的惯性思维。

最后,db.js模块导出defineModel函数:

exports.defineModel = defineModel;

定义模型

在data目录下新建“model”文件夹,并在model文件夹中添加“Notices.js”。在Notices中,先引入需要的模块:

var db = require('../db');
var seq = require('sequelize');

然后定义数据模型对象:

var Model = db.defineModel('Notices', {
  content: seq.TEXT,
  title: seq.STRING(30),
  startDate: seq.BIGINT,
  expireDate: seq.BIGINT,
  gmId: seq.INTEGER(10),
});

// 导出模型对象
module.exports = Model;

引入的db模块就是前面对sequelize的封装,然后通过defineModel()函数定义模型,添加公共字段。

在这里引入sequelize模块主要是为了定义模型的时候指定数据类型。

同步数据结构到数据库

当模型定义后,需要在数据库中建立对应的数据表,这时候需要做结构的同步,可以使用以下方法进行同步:

Model.sync();

如果数据库中已经存在该模型对应的表,则不会进行同步操作,如果想要强制进行数据结构的同步,可以通过force参数指定:

Model.sync({force: true});

使用模型

在Notices.js文件中可以直接使用Model对象进行操作,如果是外部文件,需要先引入Notices模块

var Notices = require('../data/model/Notices');

添加数据

通过数据模型对象的create方法可以添加一条数据,方法的返回值是一个Promise对象,所以可以直接调用Promise对象的then方法进行后续操作。

Notices.create({
  content: '我是公告内容。',
  title: '系统公告的标题',
  gmId: '10086',
  status: 0,
  expireDate: 1527396599123,
  startDate: Date.now()
}).then((data) => {
  res.json({ code: 0, msg: '公告发布成功', result: data });
});

then方法的参数是一个function对象,该function对象有一个data参数,这个data参数就是前面create方法操作的数据对象,可以从data里面获得数据在数据库中的id是什么。

通过await和async来实现同步编程效果

通过then的方式很像是嵌套function的回调式异步编程,有些有不喜欢嵌套function的人可以采用await来实现同步编程的效果,更多关于await的用法这里不讨论。

(async () => {
  var data = await Notices.create({
    content: '我是公告内容。',
    title: '系统公告的标题',
    gmId: '10086',
    status: 0,
    expireDate: 1527396599123,
    startDate: Date.now()
  });

  res.json({ code: 0, msg: '公告发布成功', result: data });
})();

await修饰的函数调用必须写在async修改的函数里面,否则会报错,所以这里在最外层包了一个即时函数。

关于即时函数的概念可以参考《JavaScript面向对象编程指南》这本书,里面说的挺详细的。简单说就是定义后立刻调用的一个函数。

修改数据

使用模型对象的update方法可以修改数据:

Notices.update({
  status: 2
}, {
  where: {id: 100}
});

updata(values, opts)方法的第一个参数是要修改的数据集合,字段名称和数据表对应。第二个参数是相关的一些操作参数,where用于限制修改的数据的条件,和SQL语句的where作用一样。

上面的效果是修改id为100的数据的status字段的值为2。

查询数据

通过数据模型对象的find相关的方法可以实现查询效果:

查询所有数据

Notices.findAll();

改方法会返回Notices表中所有的数据,返回值依然是一个Promise对象。

条件查询

Notices.findAll({order: [['createAt', 'DESC']], limit: 10, where: {'status': 0}});
  • order字段用于指定排序规则,这里指定以createAt字段做降序排序。
  • limit字段用于指定查询的数据量,这里表示返回前10条数据。
  • where字段用于指定条件查询,这里表示查询status为0的数据。

删除数据

通过数据模型对象的destroy方法可以销毁一条数据,具体用法和查询、修改等类似。

但是通常我们做删除操作的时候并不是真的将数据从数据库中抹除,而是通过数据的状态字段去标识,方便后续维护。所以每个表通常都会定义一个status字段。

复杂的where条件

在sequelize中,还存在一个Op对象,用于处理复杂的条件操作。

[案例一]

var seq = require('sequelize');
var Op = seq.Op;

// 其它代码... 

Model.update({
  status: 2,
  gmId: 10086
}, {
  where: {
    id: {
      [Op.in]: [1, 4, 2, 8, 13, 20]
    }
  }
});

上面这段代码表示修改status的值为2,修改gmId的值为10086。修改的条件的,数据的id字段必须是在[1, 4, 2, 8, 13, 20]这个数组中的数据。

[案例二]

var date = Date.now();

Model.findAll({
  where: {
    status: 0, 
    sendDate: {[Op.lte]: date}, 
    expireDate: {[Op.gte]: date},
    [Op.or]: [
      {to: 1000017},
      {to: 0}
    ]
  }
});

上面这段代码表示查询所有sendDate小于等于当前时间,并且expireDate大于等于当前时间,且status的值为0,并且to字段的值为1000017或者为0。

参考文档

以上也只是举了一部分例子进行简单说明而已,详细的可以查考这份文档,虽然是英文的,但是稍微花点时间应该多少是可以看懂的。

http://docs.sequelizejs.com/identifiers.html

【写在文末:ORM方便了数据库的操作,但是对于很多复杂的业务,它可能也并不能很好的解决,所以某些特定需求还是需要SQL来实现。】

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
JS之小练习代码
Oct 12 Javascript
JavaScript DOM 学习第七章 表单的扩展
Feb 19 Javascript
常用的JavaScript WEB操作方法分享
Feb 28 Javascript
JavaScript从0开始构思表情插件
Jul 26 Javascript
js实现九宫格的随机颜色跳转
Feb 19 Javascript
JS数组操作之增删改查的简单实现
Aug 21 Javascript
JavaScript实现的仿新浪微博原生态输入字数即时检查功能【兼容IE6】
Sep 26 Javascript
js原生日历的实例(推荐)
Oct 31 Javascript
详解vue-cli 2.0配置文件(小结)
Jan 14 Javascript
angular4中引入echarts的方法示例
Jan 29 Javascript
Node.js中出现未捕获异常的处理方法
Jun 29 Javascript
Vue过滤器,生命周期函数和vue-resource简单介绍
Jan 12 Vue.js
基于zepto.js实现登录界面
Oct 09 #Javascript
浅谈在koa2中实现页面渲染的全局数据
Oct 09 #Javascript
jQuery实现html双向绑定功能示例
Oct 09 #jQuery
jqueryUI tab标签页代码分享
Oct 09 #jQuery
ES6学习教程之模板字符串详解
Oct 09 #Javascript
ES6学习教程之块级作用域详解
Oct 09 #Javascript
JavaScript实现短信倒计时60s
Oct 09 #Javascript
You might like
文件上传的实现
2006/10/09 PHP
一个用于mysql的数据库抽象层函数库
2006/10/09 PHP
php输出表格的实现代码(修正版)
2010/12/29 PHP
PHP队列用法实例
2014/11/05 PHP
Laravel 5.3 学习笔记之 安装
2016/08/28 PHP
php生成随机数/生成随机字符串的方法小结【5种方法】
2020/05/27 PHP
让你的PHP,APACHE,NGINX支持大文件上传
2021/03/09 PHP
关于this和self的使用说明
2010/08/01 Javascript
javaScript实现复选框全选反选事件详解
2020/11/20 Javascript
Vue Router的懒加载路径的解决方法
2018/06/21 Javascript
JS中实现隐藏部分姓名或者电话号码的代码
2018/07/17 Javascript
JS数组及对象遍历方法代码汇总
2020/06/16 Javascript
[44:15]DOTA2上海特级锦标赛主赛事日 - 5 败者组决赛Liquid VS EG第二局
2016/03/06 DOTA
[47:45]DOTA2-DPC中国联赛 正赛 Phoenix vs Dragon BO3 第一场 2月26日
2021/03/11 DOTA
Django在Win7下的安装及创建项目hello word简明教程
2014/07/14 Python
python的变量与赋值详细分析
2017/11/08 Python
通过python+selenium3实现浏览器刷简书文章阅读量
2017/12/26 Python
Python使用matplotlib绘制余弦的散点图示例
2018/03/14 Python
django 发送手机验证码的示例代码
2018/04/25 Python
Python常见的pandas用法demo示例
2019/03/16 Python
python算法与数据结构之冒泡排序实例详解
2019/06/22 Python
Python爬虫实例之2021猫眼票房字体加密反爬策略(粗略版)
2021/02/22 Python
html5视频媒体标签video的使用方法及完整参数说明详解
2019/09/27 HTML / CSS
美国顶级户外凉鞋品牌:Chacos
2017/03/27 全球购物
Dr. Martens马汀博士澳大利亚官网:马丁靴鼻祖
2019/07/02 全球购物
Java中实现多态的机制
2015/08/09 面试题
《狐假虎威》教学反思
2014/02/07 职场文书
师恩难忘教学反思
2014/04/27 职场文书
2014年党的群众路线活动个人整改措施
2014/10/28 职场文书
招标保密承诺书
2015/01/20 职场文书
2015年五一劳动节活动总结
2015/02/09 职场文书
2015学校六五普法工作总结
2015/04/22 职场文书
请病假条范文
2015/08/17 职场文书
使用Pytorch实现two-head(多输出)模型的操作
2021/05/28 Python
MyBatis-Plus 批量插入数据的操作方法
2021/09/25 Java/Android
css3属性选择器 “~”(波浪号) “,”(逗号) “+”(加号)和 “>”(大于号)
2022/04/19 HTML / CSS