时间:2021-07-01 10:21:17 帮助过:17人阅读
这篇文章主要使用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`;
Sequelize
的where
配置项基本上完全支持了SQL
的where
子句的功能,非常强大。我们一步步来进行介绍。
Sequelize
:
var users = yield User.findAll({ ‘where‘: { ‘id‘: [1, 2, 3], ‘nick‘: ‘a‘, ‘department‘: null } }); console.log(users);
SQL
:
SELECT `id`, `emp_id`, `nick`, `department`, `created_at`, `updated_at` FROM `users` AS `user` WHERE `user`.`id` IN (1, 2, 3) AND `user`.`nick`=‘a‘ AND `user`.`department` IS NULL;
可以看到,k: v
被转换成了k = v
,同时一个对象的多个k: v
对被转换成了AND
条件,即:k1: v1, k2: v2
转换为k1 = v1 AND k2 = v2
。
这里有2个要点:
如果v是null
,会转换为IS NULL
(因为SQL
没有= NULL
这种语法)
如果v是数组,会转换为IN
条件(因为SQL
没有=[1,2,3]
这种语法,况且也没数组这种类型)
操作符是对某个字段的进一步约束,可以有多个(对同一个字段的多个操作符会被转化为AND
)。
Sequelize
:
var users = yield User.findAll({ ‘where‘: { ‘id‘: { ‘$eq‘: 1, // id = 1 ‘$ne‘: 2, // id != 2 ‘$gt‘: 6, // id > 6 ‘$gte‘: 6, // id >= 6 ‘$lt‘: 10, // id < 10 ‘$lte‘: 10, // id <= 10 ‘$between‘: [6, 10], // id BETWEEN 6 AND 10 ‘$notBetween‘: [11, 15], // id NOT BETWEEN 11 AND 15 ‘$in‘: [1, 2], // id IN (1, 2) ‘$notIn‘: [3, 4] // id NOT IN (3, 4) }, ‘nick‘: { ‘$like‘: ‘%a%‘, // nick LIKE ‘%a%‘ ‘$notLike‘: ‘%a‘ // nick NOT LIKE ‘%a‘ }, ‘updated_at‘: { ‘$eq‘: null, // updated_at IS NULL ‘$ne‘: null // created_at IS NOT NULL } } });
SQL
:
SELECT `id`, `emp_id`, `nick`, `department`, `created_at`, `updated_at` FROM `users` AS `user` WHERE ( `user`.`id` = 1 AND `user`.`id` != 2 AND `user`.`id` > 6 AND `user`.`id` >= 6 AND `user`.`id` < 10 AND `user`.`id` <= 10 AND `user`.`id` BETWEEN 6 AND 10 AND `user`.`id` NOT BETWEEN 11 AND 15 AND `user`.`id` IN (1, 2) AND `user`.`id` NOT IN (3, 4) ) AND ( `user`.`nick` LIKE ‘%a%‘ AND `user`.`nick` NOT LIKE ‘%a‘ ) AND ( `user`.`updated_at` IS NULL AND `user`.`updated_at` IS NOT NULL );
这里我们发现,其实相等条件k: v
这种写法是操作符写法k: {$eq: v}
的简写。而要实现不等条件就必须使用操作符写法k: {$ne: v}
。
上面我们说的条件查询,都是AND
查询,Sequelize
同时也支持OR
、NOT
、甚至多种条件的联合查询。
Sequelize
:
var users = yield User.findAll({ ‘where‘: { ‘$and‘: [ {‘id‘: [1, 2]}, {‘nick‘: null} ] } });
SQL
:
SELECT `id`, `emp_id`, `nick`, `department`, `created_at`, `updated_at` FROM `users` AS `user` WHERE ( `user`.`id` IN (1, 2) AND `user`.`nick` IS NULL );
Sequelize
:
var users = yield User.findAll({ ‘where‘: { ‘$or‘: [ {‘id‘: [1, 2]}, {‘nick‘: null} ] } });
SQL
:
SELECT `id`, `emp_id`, `nick`, `department`, `created_at`, `updated_at` FROM `users` AS `user` WHERE ( `user`.`id` IN (1, 2) OR `user`.`nick` IS NULL );
Sequelize
:
var users = yield User.findAll({ ‘where‘: { ‘$not‘: [ {‘id‘: [1, 2]}, {‘nick‘: null} ] } });