0 前述

  • 学习sequelize.js

  • 官方文档: http://docs.sequelizejs.com/manual/installation/getting-started.html

  • 本文档对应的github路径: https://github.com/alex-my/javascript-learn/tree/master/sequelize

  • 本文需要一点点ES6的知识,如果你不懂,可以看看阮一峰写的ECMAScript 6 入门

  • 本文关于事务SQL语句章节因为报错,因此没有写,以后补上

  • 小项目不是很喜欢外键触发器之类的东西,因此也没有写表关联相关的章节

  • 请诸君耐心的看

  • 个人博客来源: Sequelize.js 入门

  • Keylala在线工具

  • 程序员导航

1 环境搭建

  • 创建文件夹sequelize,然后在文件夹中执行npm init,这样就得到一个基础的工程

  • 进入文件夹sequelize,执行命令yarn add sequelize mysql2,也可以使用npm命令

  • 创建数据库test_sequelize

    CREATE DATABASE test_sequelize DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;
    
  • 创建以下文件夹

    • sequelize/src
    • sequelize/src/app
    • sequelize/src/db
    • sequelize/src/utils
  • 新增文件sequelize/src/db/index.js

    const Sequelize = require('sequelize');const dbConfig = {database: 'test_sequelize',username: 'root',password: '123456',host: '127.0.0.1',dialect: 'mysql', // 'mysql'|'sqlite'|'postgres'|'mssql'
    };const sequelize = new Sequelize(dbConfig.database, dbConfig.username, dbConfig.password, {host: dbConfig.host,dialect: dbConfig.dialect,operatorsAliases: false,// 设置时区timezone: '+08:00',pool: {max: 5,min: 0,acquire: 30000,idle: 10000},// define: {// 全局设置引擎, 默认是 InnoDB//     engine: 'MYISAM', // SQLite only// storage: 'path/to/database.sqlite'
    });module.exports = sequelize;
    
  • 新增文件sequelize/src/app/1-getstarted/index.js

    const db = require('../../db');db.authenticate().then(() => {console.log('Connection has been established successfully.');}).catch(err => {console.error('Unable to connect to the database:', err);});
    
  • sequelize/src/app/1-getstarted目录下执行node index.js,看是否能够连接成功

    Executing (default): SELECT 1+1 AS result
    Connection has been established successfully.
    
  • 新增文件sequelize/src/utils/random.js,用于生成随机数

    const crypto = require('crypto');const getRandomString = (len = 16) => {const buf = crypto.randomBytes(len);return buf.toString('hex');
    }module.exports = {getRandomString
    }
    
  • 至此环境搭建完毕

2 第一个示例

  • 新增文件sequelize/src/app/2-firstdemo/index.js

    const sequelize = require('sequelize');
    const db = require('../../db');
    const random = require('../../utils/random');// 定义一个 user model
    const {STRING
    } = sequelize;const User = db.define('user', {user_name: {type: STRING(32),},password: {type: STRING(32),}
    });const createTable = async () => {// 可以选择在 应用/服务器 启动的时候,把 User 映射到数据库中,比如这里会在数据库中自动创建一张表: users// 如果 force 为 true, 则每次都会重建表 usersawait User.sync({force: true,});
    }const createUser = async () => {// 创建几个用户for (let i = 0; i < 5; i++) {const userName = random.getRandomString(8);const password = random.getRandomString(16);const user = await User.create({user_name: userName,password});// sequelize 会默认加上 id, createdAt, updatedAt 字段console.log(user.id, user.createdAt, user.updatedAt);}
    }const queryAll = async () => {// 查询所有的结果const users = await User.findAll();users.forEach((user) => console.log('findAll', user.id, user.user_name));
    }(async () => {console.log('------------- createTable');await createTable();console.log('------------- createUser');await createUser();console.log('------------- queryAll');await queryAll();
    })();
    
  • sequelize/src/app/2-firstdemo下执行node index.js, 可以发现创建了表,创建了角色,并且全部搜索出来了

  • 需要注意的是, Sequelize使用的是异步,返回值是Promises, 比如const user = User.findOne(); console.log(user.id)输出的是undefined,看日志可以发现,在输出之后才执行的SELECT id, user_name, password, createdAt, updatedAt FROM users AS user LIMIT 1

  • 你需要使用如下方式来获取数据

    User.findOne().then(user => console.log(user.id))
    
  • 也可以使用本文的方式,使用async/await

    const user = User.findOne();
    console.log(user.id);
    

3 模型定义

  • 新增文件sequelize/src/app/3-model-define/index.js

    const sequelize = require('sequelize');
    const db = require('../../db');const {INTEGER,STRING,DATE,NOW,JSON
    } = sequelize;// 定义一个账号const Account = db.define('account', {// id (实际上 Sequelize 默认会自动生成一个自增 id)id: {type: INTEGER,autoIncrement: true,// 做为主键primaryKey: true,},// 账号ID为一个整型,且不能为空accountId: {type: INTEGER.UNSIGNED,allowNull: false,// 账号id需要唯一性,这个是永远不能改变的值,特别是在分表的情况下,用自增ID不小心就会重复了unique: true,},// 账号名称,字符串,范围是 4~32accountName: {// 如果不指定 STRING 长度,则默认是 255type: STRING(32),validate: {// 限制长度范围min: 4,max: 32,},// 账号需要唯一性,登录时候使用unique: true,},// 密码password: {type: STRING(128),allowNull: false,},// 昵称nickName: {type: STRING(32),validate: {min: 4,max: 32,},// 假设昵称后要加上 id 值get() {const id = this.getDataValue('id');return this.getDataValue('nickName') + '-' + id;},},// 邮箱email: {type: STRING(64),allowNull: false,validate: {// 格式必须为 邮箱格式isEmail: true,},// set 假设数据库中存储的邮箱都要是大写的,可以在此处改写set(val) {this.setDataValue('email', val.toUpperCase());},},// 注册日期 (实际上 Sequelize 默认会自动生成一个 createdAt 字段)registerAt: {type: DATE,defaultValue: NOW,},// 属性,这里用 JSON 格式写入profile: {type: JSON,},// 还支持外键功能, 不过我不喜欢使用, 项目换人了,触发器, 存储过程, 外键 这些东西就比较麻烦了}, {getterMethods: {// 自定义函数, brief 返回该账号的简要信息brief() {return `${this.accountId} ${this.accountName} ${this.nickName}`;},},setterMethods: {},// classMethods 和 instanceMethods 在 版本4 被移除了// 详见: http://docs.sequelizejs.com/manual/tutorial/upgrade-to-v4.html#config-options// 定义 类 级别的函数,可以用 Account 调用classMethods: {getCMethod() {return 'classMethods';}},// 定义 实例 级别的函数,用 account 调用instanceMethods: {getIMethod() {return 'instanceMethods';}},// 也可以在 src/db/index 中定义全局的函数// 设置为 false 之后,将不会自动加上 createdAt, updatedAt 这两个字段timestamps: true,// 假设我们需要 创建和更新 这两个字段,但不喜欢驼峰命名法// 设置为 true 之后,自动增加的字段就会用下划线命名: created_at, updated_atunderscored: true,// 也可以分别设置 createdAt, updatedAt 是否需要// 假设我们喜欢 date 这个名字表示创建时间createdAt: 'date',// 不想要 updatedAt 这个字段updatedAt: false,// 设置为 true 之后,则不会真正的删除数据,而是设置 deletedAtparanoid: true,// 也可以重命名 deletedAtdeletedAt: 'deleteTime',// 定义表名, 默认会生成一个 accounts 的表tableName: 'account',// 设置引擎格式,默认是 InnoDB 的,这是对单个表有效的// engine: 'MYISAM',// 写表注释comment: '账号表',// 可以在定义 字段的时候添加索引,不过在这个地方加索引看的会更清晰indexes: [// email 需要唯一{unique: true,fields: ['email']},// 创建一个 符合索引{// 默认名字 [table]_[fields],巨丑name: 'select_index',fields: ['accountName', 'email', 'password'],}]}
    );const createTable = async () => {await Account.sync({force: true,});
    };(async () => {console.log('------------- createTable');await createTable();
    })();
    
  • 字段的类型有很多种,比如常用的STRINGTEXTINTEGERFLOATDOUBLEDATE,更多的类型请见: DataTypes

  • 在定义模型的时候,可以直接在参数中直接写getset函数,这样可以在获取/设置 之前进行一些处理,例如nickName中,实际获取的nickName后面还加上了id值,在email中,邮箱全被设置为大写了

  • 我们也可以在新建更新保存的时候进行一些验证,在字段中的validate属性中指定,比如在email中会验证是否是isEmail,如果在这三个操作之前没有检测到,在操作时候会抛出异常。Sequelize使用了validator.js进行验证。需要注意的是,如果一个字段允许为NULL,即allowNull:true,当值为NULL的时候,validate不会进行验证

4 模型使用

  • 新增文件sequelize/src/app/4-model-usage/index.js

    const sequelize = require('sequelize');
    const db = require('../../db');const {INTEGER,STRING,Op,
    } = sequelize;const Role = db.define('role', {role_id: {type: INTEGER.UNSIGNED,allowNull: false,},role_name: {type: STRING(32),allowNull: false,unique: true,validate: {min: 4,max: 32,}},level: {type: INTEGER,defaultValue: 1,}
    }, {underscored: true,paranoid: true,
    });const createTable = async () => {await Role.sync({force: true,});
    };const createRoles = async () => {for (let i = 1; i <= 5; i++) {await Role.create({role_id: i,role_name: `name-${i}`,})}
    }const findUsage = async () => {// 根据 id 查找const role1 = await Role.findById(1);console.log(`findUsage/findById id: ${role1.id}, name: ${role1.role_name}`);// 根据条件查找一条数据, level=1 的角色有多个const role2 = await Role.findOne({where: {level: 1,}});console.log(`findUsage/findOne id: ${role2.id}, name: ${role2.role_name}`);const role3 = await Role.findOne({where: {level: 1,},attributes: ['id', 'role_id'],});// 结果中并不包含 levelconsole.log(`findUsage/findOne id: ${role3.id}, role_id: ${role3.role_id}, level: ${role3.level}`);// 如果数据库中没有,则会按照 defaults 生成一条数据, 并且 created 字段为 true// 如果数据库中有该数据,则 created 字段为 false// 返回的结果是一个数组, 第一个元素为搜索结果,第二个元素为 boolean,表示是否是新建的数据const [role4, created] = await Role.findOrCreate({where: {role_name: 'alex'},defaults: {role_id: 5,role_name: 'alex',level: 15,},});console.log(`findUsage/findOrCreate created: ${created}, role4: ${JSON.stringify(role4)}`);// 查找全部数据,并获得数量// 返回值 count: 数据个数// 返回值 rows: 包含数据的集合const result5 = await Role.findAndCountAll({where: {level: 1,}});console.log(`findUsage/findAndCountAll count: ${result5.count}, rows: ${JSON.stringify(result5.rows)}`);
    }const findAllUsage = async () => {// 查找全部, 可以在其中放入查询条件和限制条件console.log('\r\n');await Role.findAll({where: {id: [1, 2, 3, 4, 5]},limit: 3,});// all() 是 findAll 的别名console.log('\r\n');// where 中可以灵活的设置各种条件await Role.all({where: {level: {[Op.gt]: 1,// [Op.and]: {a: 5},           // AND (a = 5)// [Op.or]: [{a: 5}, {a: 6}],  // (a = 5 OR a = 6)// [Op.gt]: 6,                // id > 6// [Op.gte]: 6,               // id >= 6// [Op.lt]: 10,               // id < 10// [Op.lte]: 10,              // id <= 10// [Op.ne]: 20,               // id != 20// [Op.between]: [6, 10],     // BETWEEN 6 AND 10// [Op.notBetween]: [11, 15], // NOT BETWEEN 11 AND 15// [Op.in]: [1, 2],           // IN [1, 2]// [Op.notIn]: [1, 2],        // NOT IN [1, 2]// [Op.like]: '%hat',         // LIKE '%hat'// [Op.notLike]: '%hat',      // NOT LIKE '%hat'}},limit: 3,});// 也可以设置为 OR/NOT 等条件console.log('\r\n');// ((`role`.`id` IN (1, 2, 3) OR `role`.`id` > 10) AND `role`.`level` = 1)await Role.findAll({where: {level: 1,[Op.or]: [{id: [1, 2, 3]},{id: {[Op.gt]: 10}},]}});console.log('\r\n');// (`role`.`id` IN (1, 2, 3) OR `role`.`id` > 12))await Role.findAll({where: {level: 1,id: {[Op.or]: [[1, 2, 3],{[Op.gt]: 12}]}}});console.log('\r\n');// order 排序await Role.findAll({limit: 2,order: [['id'],['role_id', 'ASC'],// [sequelize.fn('max', sequelize.col('level')), 'DESC'],],// 注意 raw, 默认为 false, 这时候 Sequelize 会为搜索出的每一条数据生成一个 Role 实例,用于更新,删除等操作// 但当我们只想搜索出数据用于显示,并不想操作它,这个时候设置 raw: true 就会直接返回数据,而不会生成实例raw: true,});
    }const someUsage = async () => {console.log('\r\n');// countconst c1 = await Role.count();console.log(`someUsage/count c1: ${c1}`);const c2 = await Role.count({where: {level: {[Op.gt]: 1,}}});console.log(`someUsage/count c2: ${c2}`);// max, minconst m1 = await Role.max('level', {where: {id: {[Op.gt]: 5,}}});console.log(`someUsage/max m1: ${m1}`);// sumconst s1 = await Role.sum('level');console.log(`someUsage/sum s1: ${s1}`);
    }(async () => {console.log('------------- createTable');await createTable();console.log('------------- createRoles');await createRoles();console.log('------------- findUsage');await findUsage();console.log('------------- findAllUsage');await findAllUsage();console.log('------------- someUsage');await someUsage();
    })();
    

5 查询相关

  • SELECT

    • 通过attributes可以指定搜索的字段
    Role.findAll({attributes: ['role_id', 'role_name'],
    });
    // SELECT `role_id`, `role_name`
    
  • AS

    • 也可以在``
    Role.findAll({attributes: ['role_id', ['role_name', 'name']],
    });
    // SELECT `role_id`, `role_name` AS `name` ...
    
  • COUNT,AVG,MAX,MIN,SUM等函数

    • 可以使用sequelize.fn来执行这些函数
    Role.findAll({attributes: [[sequelize.fn('COUNT', sequelize.col('*')), 'total_count']],
    });
    // SELECT COUNT(*) AS `total_count` ...Role.findAll({attributes: [[sequelize.fn('COUNT', 1), 'total_count']],
    });
    // SELECT COUNT(1) AS `total_count` ...
    
  • WHERE

    • 默认是 AND
    Role.findAll({where: {id: 5,level: 1,},
    });
    // ... where `role`.`id` = 5 AND `role`.`level` = 1
    
    • OR 的写法
    Role.findAll({where: {[Op.or]: [{ id: 2 }, { id: 3 }],},
    });
    // ... where `role`.`id` = 2 OR `role`.`id` = 3// 另一种写法
    Role.findAll({where: {id: {[Op.or]: [2, 3],},},
    });
    // ... where `role`.`id` = 2 OR `role`.`id` = 3// 不同字段的写法
    Role.findAll({where: {[Op.or]: [{ id: 2 }, { level: 3 }],},
    });
    // ... where `role`.`id` = 2 OR `role`.`level` = 3
    
  • 复杂点的写法

    Role.findAll({where: {[Op.or]: [{ id: 2 }, { level: 3 }],[Op.and]: [{ role_id: { [Op.ne]: 10001 } }],},
    });
    // ... where (`role`.`id` = 2 OR `role`.`level` = 3) AND (`role`.`role_id` != 10001)
    

6 实例

  • 可以创建一个没有写入数据库的实例,当然,创建之后也可以用save命令存入数据库中

    const role = Role.build({role_id: 1,role_name: 'name-1'
    });
    console.log(JSON.stringify(role));  // 可以发现, role.id 的值是 NULL
    await role.save(); // 在需要的时候调用 save 命令,可以将数据存入数据库中
    console.log(JSON.stringify(role));  // 这时候,role.id 有值了
    
  • 也可以直接使用create命令直接创建一条写入数据库的数据,这在前文中有多处这样的写法

    const role = await Role.create({role_id: 2,role_name: 'name-2',
    });
    console.log(JSON.stringify(role));
    
  • 批量创建实例

    • 使用bulkCreate来批量创建

      const l = [];
      for (let i = 0; i < 5; i++) {l.push({role_id: 1000 + i,role_name: `bulkname-${i}`,});
      }const result = await Role.bulkCreate(l);
      console.log('result:', JSON.stringify(result));
      // 输出
      // Executing (default): INSERT INTO `roles` (`id`,`role_id`,`role_name`,`level`,`created_at`,`updated_at`) VALUES (NULL,1000,'bulkname-0',1,'2018-10-15 15:38:29','2018-10-15 15:38:29'),(NULL,1001,'bulkname-1',1,'2018-10-15 15:38:29','2018-10-15 15:38:29'),(NULL,1002,'bulkname-2',1,'2018-10-15 15:38:29','2018-10-15 15:38:29'),(NULL,1003,'bulkname-3',1,'2018-10-15 15:38:29','2018-10-15 15:38:29'),(NULL,1004,'bulkname-4',1,'2018-10-15 15:38:29','2018-10-15 15:38:29');
      // result: [{"id":1,"role_id":1000,"role_name":"bulkname-0","level":1,"created_at":"2018-10-15T07:38:29.902Z","updated_at":"2018-10-15T07:38:29.902Z"},{"id":2,"role_id":1001,"role_name":"bulkname-1","level":1,"created_at":"2018-10-15T07:38:29.902Z","updated_at":"2018-10-15T07:38:29.902Z"},{"id":3,"role_id":1002,"role_name":"bulkname-2","level":1,"created_at":"2018-10-15T07:38:29.902Z","updated_at":"2018-10-15T07:38:29.902Z"},{"id":4,"role_id":1003,"role_name":"bulkname-3","level":1,"created_at":"2018-10-15T07:38:29.902Z","updated_at":"2018-10-15T07:38:29.902Z"},{"id":5,"role_id":1004,"role_name":"bulkname-4","level":1,"created_at":"2018-10-15T07:38:29.902Z","updated_at":"2018-10-15T07:38:29.902Z"}]
      
    • 限制字段

      const l = [];
      for (let i = 0; i < 5; i++) {l.push({role_id: 1000 + i,role_name: `bulkname-${i}`,level: i + 5,});
      }const result = await Role.bulkCreate(l, {// 这样创建语句中只有 role_id 和 role_name,会忽略 levelfields: ['role_id', 'role_name']
      });
      
  • 更新

    • 更新表中符合条件的数据(批量更新)

      const result = await Role.update({level: 4
      }, {where: {}
      });
      console.log('result: ', JSON.stringify(result));
      // 输出
      // Executing (default): UPDATE `roles` SET `level`=4,`updated_at`='2018-10-15 06:51:07' WHERE (`deleted_at` > '2018-10-15 06:51:07' OR `deleted_at` IS NULL)
      // result:  [2]
      
    • 更新具体的实例

      const role = await Role.findOne({where: {id: 1}
      });
      const result2 = await role.update({level: 5
      });
      // 输出
      // Executing (default): SELECT `id`, `role_id`, `role_name`, `level`, `created_at`, `updated_at`, `deleted_at` FROM `roles` AS `role` WHERE ((`role`.`deleted_at` > '2018-10-15 06:51:07' OR `role`.`deleted_at` IS NULL) AND `role`.`id` = 1);
      // Executing (default): UPDATE `roles` SET `level`=5,`updated_at`='2018-10-15 06:51:07' WHERE `id` = 1
      // result2:  {"id":1,"role_id":1,"role_name":"name-1","level":5,"created_at":"2018-10-15T06:36:26.000Z","updated_at":"2018-10-15T06:51:07.935Z","deleted_at":null}
      
    • 更新未写入数据库的数据,相当于创建了一条新数据

      const role3 = Role.build({role_id: 3,role_name: 'name-3',
      });
      const result3 = await role3.update({role_id: 4,role_name: 'name-4',level: 4,
      });
      console.log('result3: ', JSON.stringify(result3));
      // 实际上执行的是: INSERT INTO `roles` (`role_id`,`role_name`,`level`,`updated_at`,`created_at`) VALUES (4,'name-4',4,'2018-10-15 06:57:28','2018-10-15 06:57:28')
      
  • 删除

    • 如果我们启用了软删除,即设置了paranoid:true(需要timestamps:true),则不会真正的将数据从数据库中删除,而是设置了deleted_at

    • 将表中符合条件的数据删除(批量删除)

      const result1 = await Role.destroy({where: {id: 1}
      });
      console.log('result1:', result1);
      // 输出
      // Executing (default): UPDATE `roles` SET `deleted_at`='2018-10-15 15:02:50' WHERE `deleted_at` IS NULL AND `id` = 1
      // result1: 1
      
    • 将具体的实例进行删除,这里设置了force:true,进行硬删除,把数据从数据库中删除

      const role2 = await Role.findOne({where: {id: 2}
      });
      // 可以设置 force: true, 使得数据真正从数据库中删除
      const result2 = await role2.destroy({force: true
      });
      console.log('result2:', result2);
      // 输出
      // DELETE FROM `roles` WHERE `id` = 2 LIMIT 1
      
    • 删除未写入数据库的实例进行删除

      // 软删除
      Role.build({role_id: 5,role_name: 'name-5'
      }).destroy()
      // 输出
      // UPDATE `roles` SET `deleted_at`='2018-10-15 15:14:28' WHERE `id` IS NULL AND `deleted_at` IS NULL// 硬删除
      Role.build({role_id: 5,role_name: 'name-5'
      }).destroy({force: true,
      });
      // 输出
      // DELETE FROM `roles` WHERE `id` IS NULL LIMIT 1
      
  • 增减

    • 增加值使用increment, 减少值使用decrement,用法相同

    • level加5,可以看到result中的level还是原来的数据

      const role = await Role.findById(1);
      const result = await role.increment('level', {by: 5
      });
      console.log('result:', JSON.stringify(result));
      // 输出
      // Executing (default): UPDATE `roles` SET `level`=`level`+ 5,`updated_at`='2018-10-15 16:04:35' WHERE `id` = 1
      // result: {"id":1,"role_id":1000,"role_name":"bulkname-0","level":1,"created_at":"2018-10-15T07:52:06.000Z","updated_at":"2018-10-15T07:52:06.000Z","deleted_at":null}
      

7 事务

  • 事务分为两种:

    • 一种需要我们手动执行commitrollback命令进行提交和回滚
    • 另一种是自动管理的,只要返回值都是成功resolved,则会一个个执行下去,一旦出现一个rejected,就会自行回滚

8 钩子

  • 钩子列表

    (1)beforeBulkCreate(instances, options)beforeBulkDestroy(options)beforeBulkUpdate(options)
    (2)beforeValidate(instance, options)
    (-)validate
    (3)afterValidate(instance, options)- or -validationFailed(instance, options, error)
    (4)beforeCreate(instance, options)beforeDestroy(instance, options)beforeUpdate(instance, options)beforeSave(instance, options)beforeUpsert(values, options)
    (-)createdestroyupdate
    (5)afterCreate(instance, options)afterDestroy(instance, options)afterUpdate(instance, options)afterSave(instance, options)afterUpsert(created, options)
    (6)afterBulkCreate(instances, options)afterBulkDestroy(options)afterBulkUpdate(options)
    
  • 完整列表见: Hooks file

  • 新增文件sequelize/src/app/7-hooks/index.js

    const sequelize = require('sequelize');
    const db = require('../../db');const {INTEGER,STRING,
    } = sequelize;const Role = db.define('role', {role_id: {type: INTEGER.UNSIGNED,allowNull: false,},role_name: {type: STRING(32),allowNull: false,unique: true,validate: {min: 4,max: 32,},},level: {type: INTEGER,defaultValue: 1,},}, {underscored: true,paranoid: true,// 使用钩子方法1: 在定义的时候新增钩子hooks: {beforeCreate: (role, options) => {console.log('beforeCreate ...');role.level = 100;},// 可以写多个钩子}}
    );// 使用钩子方法2
    Role.hook('beforeValidate', (role, options) => {console.log('beforeValidate ...');
    });// 使用钩子方法3
    Role.afterCreate((role, options) => {console.log('afterCreate ...');console.log('role created success,', JSON.stringify(role));
    });const createTable = async () => {await Role.sync({force: true,});
    };const createRole = async () => {await Role.create({role_id: 1,role_name: 'name-1'});// 输出// beforeValidate ...// beforeCreate ...// Executing (default): INSERT INTO `roles` (`id`,`role_id`,`role_name`,`level`,`created_at`,`updated_at`) VALUES (DEFAULT,1,'name-1',100,'2018-10-15 17:08:52','2018-10-15 17:08:52');// afterCreate ...// role created success, {"level":100,"id":1,"role_id":1,"role_name":"name-1","updated_at":"2018-10-15T09:08:52.923Z","created_at":"2018-10-15T09:08:52.923Z"}
    }(async () => {console.log('------------- createTable');await createTable();console.log('------------- createRole');await createRole();
    })();
    

9 SQL语句

  • sequelize中还可以直接使用sql语句,但在测试报错: TypeError: sequelize.query is not a function,因此后续还有个功能: 替换,用 ? 或者 :key 替换值 就没有继续研究了

  • 新增文件sequelize/src/app/8-sql/index.js

    const sequelize = require('sequelize');
    const db = require('../../db');const {INTEGER,STRING,
    } = sequelize;const Role = db.define('role', {role_id: {type: INTEGER.UNSIGNED,allowNull: false,},role_name: {type: STRING(32),allowNull: false,unique: true,validate: {min: 4,max: 32,},},level: {type: INTEGER,defaultValue: 1,},}, {underscored: true,paranoid: true,}
    );const createTable = async () => {await Role.sync({force: true,});
    };const createRoles = async () => {const l = [];for (let i = 1; i <= 5; i++) {l.push({role_id: i,role_name: `name-${i}`,level: i + 5});}await Role.bulkCreate(l);
    }const rawQueryUsage = async () => {// 实际上报错: 找不到 sequelize.query 这个函数const result1 = await sequelize.query("SELECT * FROM roles");console.log('result 1:', JSON.stringify(result1));console.log('\r\n');const result2 = await sequelize.query("SELECT * FROM roles", {type: sequelize.QueryTypes.SELECT});console.log('result 2:', JSON.stringify(result2));
    }(async () => {console.log('------------- createTable');await createTable();console.log('------------- createRoles');await createRoles();console.log('------------- rawQueryUsage');await rawQueryUsage();
    })();
    

Sequelize.js 入门相关推荐

  1. js模板字符串自定义类名_【Vue.js 入门到实战教程】07Vue 组件注册 | 基本使用和组件嵌套...

    来源 | https://xueyuanjun.com/post/21929除了前面介绍的基本语法之外,Vue.js 还支持通过组件构建复杂的功能模块,组件可以称得上是 Vue.js 的灵魂,是 Vu ...

  2. React.js入门笔记

    # React.js入门笔记 核心提示 这是本人学习react.js的第一篇入门笔记,估计也会是该系列涵盖内容最多的笔记,主要内容来自英文官方文档的快速上手部分和阮一峰博客教程.当然,还有我自己尝试的 ...

  3. Ember.js入门教程、博文汇总

    第一章 对象模型 Ember.js 入门指南--类的定义.初始化.继承 Ember.js 入门指南--类的扩展(reopen) Ember.js 入门指南--计算属性(compute properti ...

  4. node.js入门 - 9.api:http

    node一个重要任务是用来创建web服务,接下来我们就学习与此相关的一个重要的api -- http.我们使用http.createServer()创建一个http服务的实例,用来处理来自客户的请求. ...

  5. 《Node.js入门》Windows 7下Node.js Web开发环境搭建笔记

    最近想尝试一下在IBM Bluemix上使用Node.js创建Web应用程序,所以需要在本地搭建Node.js Web的开发测试环境. 这里讲的是Windows下的搭建方法,使用CentOS 的小伙伴 ...

  6. android应用案例开发大全_vue.js入门及经典应用案例总结(前端开发必看)

    <大数据和人工智能交流>头条号向广大初学者新增C .Java .Python .Scala.javascript 等目前流行的计算机.大数据编程语言,希望大家以后关注本头条号更多的内容. ...

  7. vue设置cookie的domain无效_【Vue.js入门到实战教程】16Tailwind 与 Bootstrap 的区别和使用入门...

    来源 | https://xueyuanjun.com/post/22065我们知道,从 Laravel 8 开始,自带前端脚手架代码默认兼容 Tailwind CSS 框架,取代了之前的 Boots ...

  8. Vue.js入门教程-组件注册

    一.组件创建 1.1 创建步骤 创建Vue的组件都有三个基本步骤是 [①创建组件构造器.②注册组件和③使用组件]. 1.2 基本示例 比如,我们创建一个Button组件. // 1. 创建一个组件构造 ...

  9. d3.js 入门指南 - 仪表盘

    D3的全称是Data-Driven Documents(数据驱动的文档),是一个用来做数据可视化的JavaScript函数库,而JavaScript文件的后缀通常为.js,所以D3被称为D3.js. ...

最新文章

  1. 人类偏好的“可塑性”,从博弈说起
  2. centos6.5 搭建NFS 服务
  3. ftp主要完成与远程计算机的连接,2015计算机三级《网络技术》复习重点:远程登录服务和FTP服务...
  4. linux rsync 常见错误,Linux rsync常见错误
  5. 阿里巴巴Linux开源镜像站 华为Linux开源镜像站 Linux宝塔面板
  6. SpringMVC→简介、MVC、SpringMVC工作原理、Maven搭建第一个SpringMVC、请求参数接收、重定向、文件上传、AJAX异步访问、请求参数接收绑定JSON、@注解及传参
  7. docker使用填坑记录(修改无法启动容器, 拉取国外镜像)
  8. Windows Azure Cloud Service (42) 使用Azure In-Role Cache缓存(1)Co-located Role
  9. debian or ubuntu下 anjuta配置
  10. 飞鱼星路由器常见问题解答
  11. XP系统,开机启动报NTDETECT 失败
  12. 进制转换之十进制转换为十六进制
  13. 数字逻辑课程设计#Quartus II
  14. 常见的Transforms的使用方法
  15. flv + livego + obs 实现简易直播平台(windows版+Linux版)
  16. vsan虚拟化和共享存储服务器,恰逢其时:当VSAN遇到浪潮云海桌面一体机
  17. Android 游戏存档位置分析
  18. hive linux时间戳转换,Hive 中 时间戳,字符串转换
  19. Matlab PCA 算法
  20. CHM文档打开空白的解决

热门文章

  1. Your ApplicationContext is unlikely tostart due to a @ComponentScan of the defau
  2. 专访风华高科总裁王金全:锐意进取的改革者
  3. mac使用git管理Github
  4. java线程占用的空间_linux服务器查询java线程占用的资源-Go语言中文社区
  5. Matlab学习手记——制作GIF动图
  6. Timer/Counter
  7. USB驱动转换成VISA驱动供Labview调用
  8. 优步和滴滴激战中国市场
  9. TOJ 2346.Gauß in Elementary School
  10. QT 实现图片旋转及缩放