Sequelize 和 MySQL 对照

it2026-09-20  2

如果你觉得Sequelize的文档有点多、杂,不方便看,可以看看这篇。

Sequelize 中文文档

在使用NodeJS来关系型操作数据库时,为了方便,通常都会选择一个合适的ORM(Object Relationship Model)框架。毕竟直接操作SQL比较繁琐,通过ORM框架,我们可以使用面向对象的方式来操作表。NodeJS社区有很多的ORM框架,我比较喜欢Sequelize,它功能丰富,可以非常方便的进行连表查询。

这篇文章我们就来看看,Sequelize是如何在SQL之上进行抽象、封装,从而提高开发效率的。

安装

这篇文章主要使用MySQL、Sequelize、co来进行介绍。安装非常简单:

$ npm install --save co $ npm install --save sequelize $ npm install --save mysql

代码模板如下:

var Sequelize = require('sequelize'); var co = require('co'); co(function* () { // code here }).catch(function(e) { console.log(e); });

基本上,Sequelize的操作都会返回一个Promise,在co的框架里面可以直接进行yield,非常方便。

建立数据库连接

var sequelize = new Sequelize( 'sample', // 数据库名 'root', // 用户名 'zuki', // 用户密码 { 'dialect': 'mysql', // 数据库使用mysql 'host': 'localhost', // 数据库服务器ip 'port': 3306, // 数据库服务器端口 'define': { // 字段以下划线(_)来分割(默认是驼峰命名风格) 'underscored': true } } );

定义单张表

Sequelize:

var User = sequelize.define( // 默认表名(一般这里写单数),生成时会自动转换成复数形式 // 这个值还会作为访问模型相关的模型时的属性名,所以建议用小写形式 'user', // 字段定义(主键、created_at、updated_at默认包含,不用特殊定义) { 'emp_id': { 'type': Sequelize.CHAR(10), // 字段类型 'allowNull': false, // 是否允许为NULL 'unique': true // 字段是否UNIQUE }, 'nick': { 'type': Sequelize.CHAR(10), 'allowNull': false }, 'department': { 'type': Sequelize.STRING(64), 'allowNull': true } } );

SQL:

CREATE TABLE IF NOT EXISTS `users` ( `id` INTEGER NOT NULL auto_increment , `emp_id` CHAR(10) NOT NULL UNIQUE, `nick` CHAR(10) NOT NULL, `department` VARCHAR(64), `created_at` DATETIME NOT NULL, `updated_at` DATETIME NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB;

几点说明:

建表SQL会自动执行的意思是你主动调用sync的时候。类似这样:User.sync({force: true});(加force:true,会先删掉表后再建表)。我们也可以先定义好表结构,再来定义Sequelize模型,这时可以不用sync。两者在定义阶段没有什么关系,直到我们真正开始操作模型时,才会触及到表的操作,但是我们当然还是要尽量保证模型和表的同步(可以借助一些migration工具)。自动建表功能有风险,使用需谨慎。所有数据类型,请参考文档数据类型。模型还可以定义虚拟属性、类方法、实例方法,请参考文档:模型定义其他一些特殊定义如下所示: var User = sequelize.define( 'user', { 'emp_id': { 'type': Sequelize.CHAR(10), // 字段类型 'allowNull': false, // 是否允许为NULL 'unique': true // 字段是否UNIQUE }, 'nick': { 'type': Sequelize.CHAR(10), 'allowNull': false }, 'department': { 'type': Sequelize.STRING(64), 'allowNull': true } }, { // 自定义表名 'freezeTableName': true, 'tableName': 'xyz_users', // 是否需要增加createdAt、updatedAt、deletedAt字段 'timestamps': true, // 不需要createdAt字段 'createdAt': false, // 将updatedAt字段改个名 'updatedAt': 'utime' // 将deletedAt字段改名 // 同时需要设置paranoid为true(此种模式下,删除数据时不会进行物理删除,而是设置deletedAt为当前时间 'deletedAt': 'dtime', 'paranoid': true } );

单表增删改查

通过Sequelize获取的模型对象都是一个DAO(Data Access Object)对象,这些对象会拥有许多操作数据库表的实例对象方法(比如:save、update、destroy等),需要获取“干净”的JSON对象可以调用get({‘plain’: true})。

通过模型的类方法可以获取模型对象(比如:findById、findAll等)。

Sequelize:

// 方法1:build后对象只存在于内存中,调用save后才操作db var user = User.build({ 'emp_id': '1', 'nick': '小红', 'department': '技术部' }); user = yield user.save(); console.log(user.get({'plain': true})); // 方法2:直接操作db var user = yield User.create({ 'emp_id': '2', 'nick': '小明', 'department': '技术部' }); console.log(user.get({'plain': true}));

SQL:

INSERT INTO `users` (`id`, `emp_id`, `nick`, `department`, `updated_at`, `created_at`) VALUES (DEFAULT, '1', '小红', '技术部', '2015-11-02 14:49:54', '2015-11-02 14:49:54');

Sequelize会为主键id设置DEFAULT值来让数据库产生自增值,还将当前时间设置成了created_at和updated_at字段,非常方便。

Sequelize:

// 方法1:操作对象属性(不会操作db),调用save后操作db user.nick = '小白'; user = yield user.save(); console.log(user.get({'plain': true})); // 方法2:直接update操作db user = yield user.update({ 'nick': '小白白' }); console.log(user.get({'plain': true}));

SQL:

UPDATE `users` SET `nick` = '小白白', `updated_at` = '2015-11-02 15:00:04' WHERE `id` = 1;

更新操作时,Sequelize将将当前时间设置成了updated_at,非常方便。

如果想限制更新属性的白名单,可以这样写:

// 方法1 user.emp_id = '33'; user.nick = '小白'; user = yield user.save({'fields': ['nick']}); // 方法2 user = yield user.update( {'emp_id': '33', 'nick': '小白'}, {'fields': ['nick']} });

这样就只会更新nick字段,而emp_id会被忽略。这种方法在对表单提交过来的一大推数据中只更新某些属性的时候比较有用。

Sequelize:

yield user.destroy();

SQL:

DELETE FROM `users` WHERE `id` = 1;

这里有个特殊的地方是,如果我们开启了paranoid(偏执)模式,destroy的时候不会执行DELETE语句,而是执行一个UPDATE语句将deleted_at字段设置为当前时间(一开始此字段值为NULL)。我们可以使用user.destroy({force: true})来强制删除,从而执行DELETE语句进行物理删除。

查全部

Sequelize:

var users = yield User.findAll(); console.log(users);

SQL:

SELECT `id`, `emp_id`, `nick`, `department`, `created_at`, `updated_at` FROM `users`;

限制字段

Sequelize:

var users = yield User.findAll({ 'attributes': ['emp_id', 'nick'] }); console.log(users);

SQL:

SELECT `emp_id`, `nick` FROM `users`;

字段重命名

Sequelize:

var users = yield User.findAll({ 'attributes': [ 'emp_id', ['nick', 'user_nick'] ] }); console.log(users);

SQL:

SELECT `emp_id`, `nick` AS `user_nick` FROM `users`;

https://segmentfault.com/a/1190000003987871

最新回复(0)