时间:2021-07-01 10:21:17 帮助过:13人阅读
基本上,Sequelize
的操作都会返回一个Promise
,在co
的框架里面可以直接进行yield
,非常方便。
- <code class="javascript"><span class="hljs-keyword">var sequelize = <span class="hljs-keyword">new Sequelize(
- <span class="hljs-string">‘sample‘, <span class="hljs-comment">// 数据库名
- <span class="hljs-string">‘root‘, <span class="hljs-comment">// 用户名
- <span class="hljs-string">‘zuki‘, <span class="hljs-comment">// 用户密码
- {
- <span class="hljs-string">‘dialect‘: <span class="hljs-string">‘mysql‘, <span class="hljs-comment">// 数据库使用mysql
- <span class="hljs-string">‘host‘: <span class="hljs-string">‘localhost‘, <span class="hljs-comment">// 数据库服务器ip
- <span class="hljs-string">‘port‘: <span class="hljs-number">3306, <span class="hljs-comment">// 数据库服务器端口
- <span class="hljs-string">‘define‘: {
- <span class="hljs-comment">// 字段以下划线(_)来分割(默认是驼峰命名风格)
- <span class="hljs-string">‘underscored‘: <span class="hljs-literal">true
- }
- }
- );</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code>
Sequelize
:
- <code class="javascript"><span class="hljs-keyword">var User = sequelize.define(
- <span class="hljs-comment">// 默认表名(一般这里写单数),生成时会自动转换成复数形式
- <span class="hljs-comment">// 这个值还会作为访问模型相关的模型时的属性名,所以建议用小写形式
- <span class="hljs-string">‘user‘,
- <span class="hljs-comment">// 字段定义(主键、created_at、updated_at默认包含,不用特殊定义)
- {
- <span class="hljs-string">‘emp_id‘: {
- <span class="hljs-string">‘type‘: Sequelize.CHAR(<span class="hljs-number">10), <span class="hljs-comment">// 字段类型
- <span class="hljs-string">‘allowNull‘: <span class="hljs-literal">false, <span class="hljs-comment">// 是否允许为NULL
- <span class="hljs-string">‘unique‘: <span class="hljs-literal">true <span class="hljs-comment">// 字段是否UNIQUE
- },
- <span class="hljs-string">‘nick‘: {
- <span class="hljs-string">‘type‘: Sequelize.CHAR(<span class="hljs-number">10),
- <span class="hljs-string">‘allowNull‘: <span class="hljs-literal">false
- },
- <span class="hljs-string">‘department‘: {
- <span class="hljs-string">‘type‘: Sequelize.STRING(<span class="hljs-number">64),
- <span class="hljs-string">‘allowNull‘: <span class="hljs-literal">true
- }
- }
- );
- </span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code>
SQL
:
- <code class="sql"><span class="hljs-keyword">CREATE <span class="hljs-keyword">TABLE <span class="hljs-keyword">IF <span class="hljs-keyword">NOT <span class="hljs-keyword">EXISTS <span class="hljs-string">`users` (
- <span class="hljs-string">`id` <span class="hljs-built_in">INTEGER <span class="hljs-keyword">NOT <span class="hljs-literal">NULL auto_increment ,
- <span class="hljs-string">`emp_id` <span class="hljs-built_in">CHAR(<span class="hljs-number">10) <span class="hljs-keyword">NOT <span class="hljs-literal">NULL <span class="hljs-keyword">UNIQUE,
- <span class="hljs-string">`nick` <span class="hljs-built_in">CHAR(<span class="hljs-number">10) <span class="hljs-keyword">NOT <span class="hljs-literal">NULL,
- <span class="hljs-string">`department` <span class="hljs-built_in">VARCHAR(<span class="hljs-number">64),
- <span class="hljs-string">`created_at` DATETIME <span class="hljs-keyword">NOT <span class="hljs-literal">NULL,
- <span class="hljs-string">`updated_at` DATETIME <span class="hljs-keyword">NOT <span class="hljs-literal">NULL,
- <span class="hljs-keyword">PRIMARY <span class="hljs-keyword">KEY (<span class="hljs-string">`id`)
- ) <span class="hljs-keyword">ENGINE=<span class="hljs-keyword">InnoDB;</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code>
几点说明:
建表SQL
会自动执行的意思是你主动调用sync
的时候。类似这样:User.sync({force: true});
(加force:true
,会先删掉表后再建表)。我们也可以先定义好表结构,再来定义Sequelize
模型,这时可以不用sync
。两者在定义阶段没有什么关系,直到我们真正开始操作模型时,才会触及到表的操作,但是我们当然还是要尽量保证模型和表的同步(可以借助一些migration
工具)。自动建表功能有风险,使用需谨慎。
所有数据类型,请参考文档数据类型。
模型还可以定义虚拟属性、类方法、实例方法,请参考文档:模型定义
其他一些特殊定义如下所示:
- <code class="javascript"><span class="hljs-keyword">var User = sequelize.define(
- <span class="hljs-string">‘user‘,
- {
- <span class="hljs-string">‘emp_id‘: {
- <span class="hljs-string">‘type‘: Sequelize.CHAR(<span class="hljs-number">10), <span class="hljs-comment">// 字段类型
- <span class="hljs-string">‘allowNull‘: <span class="hljs-literal">false, <span class="hljs-comment">// 是否允许为NULL
- <span class="hljs-string">‘unique‘: <span class="hljs-literal">true <span class="hljs-comment">// 字段是否UNIQUE
- },
- <span class="hljs-string">‘nick‘: {
- <span class="hljs-string">‘type‘: Sequelize.CHAR(<span class="hljs-number">10),
- <span class="hljs-string">‘allowNull‘: <span class="hljs-literal">false
- },
- <span class="hljs-string">‘department‘: {
- <span class="hljs-string">‘type‘: Sequelize.STRING(<span class="hljs-number">64),
- <span class="hljs-string">‘allowNull‘: <span class="hljs-literal">true
- }
- },
- {
- <span class="hljs-comment">// 自定义表名
- <span class="hljs-string">‘freezeTableName‘: <span class="hljs-literal">true,
- <span class="hljs-string">‘tableName‘: <span class="hljs-string">‘xyz_users‘,
- <span class="hljs-comment">// 是否需要增加createdAt、updatedAt、deletedAt字段
- <span class="hljs-string">‘timestamps‘: <span class="hljs-literal">true,
- <span class="hljs-comment">// 不需要createdAt字段
- <span class="hljs-string">‘createdAt‘: <span class="hljs-literal">false,
- <span class="hljs-comment">// 将updatedAt字段改个名
- <span class="hljs-string">‘updatedAt‘: <span class="hljs-string">‘utime‘
- <span class="hljs-comment">// 将deletedAt字段改名
- <span class="hljs-comment">// 同时需要设置paranoid为true(此种模式下,删除数据时不会进行物理删除,而是设置deletedAt为当前时间
- <span class="hljs-string">‘deletedAt‘: <span class="hljs-string">‘dtime‘,
- <span class="hljs-string">‘paranoid‘: <span class="hljs-literal">true
- }
- );</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code>
通过Sequelize
获取的模型对象都是一个DAO
(Data Access Object)对象,这些对象会拥有许多操作数据库表的实例对象方法(比如:save
、update
、destroy
等),需要获取“干净”的JSON
对象可以调用get({‘plain‘: true})
。
通过模型的类方法可以获取模型对象(比如:findById
、findAll
等)。
Sequelize
:
- <code class="javascript"><span class="hljs-comment">// 方法1:build后对象只存在于内存中,调用save后才操作db
- <span class="hljs-keyword">var user = User.build({
- <span class="hljs-string">‘emp_id‘: <span class="hljs-string">‘1‘,
- <span class="hljs-string">‘nick‘: <span class="hljs-string">‘小红‘,
- <span class="hljs-string">‘department‘: <span class="hljs-string">‘技术部‘
- });
- user = <span class="hljs-keyword">yield user.save();
- <span class="hljs-built_in">console.log(user.get({<span class="hljs-string">‘plain‘: <span class="hljs-literal">true}));
- <span class="hljs-comment">// 方法2:直接操作db
- <span class="hljs-keyword">var user = <span class="hljs-keyword">yield User.create({
- <span class="hljs-string">‘emp_id‘: <span class="hljs-string">‘2‘,
- <span class="hljs-string">‘nick‘: <span class="hljs-string">‘小明‘,
- <span class="hljs-string">‘department‘: <span class="hljs-string">‘技术部‘
- });
- <span class="hljs-built_in">console.log(user.get({<span class="hljs-string">‘plain‘: <span class="hljs-literal">true}));</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code>
SQL
:
- <code class="sql"><span class="hljs-keyword">INSERT <span class="hljs-keyword">INTO <span class="hljs-string">`users`
- (<span class="hljs-string">`id`, <span class="hljs-string">`emp_id`, <span class="hljs-string">`nick`, <span class="hljs-string">`department`, <span class="hljs-string">`updated_at`, <span class="hljs-string">`created_at`)
- <span class="hljs-keyword">VALUES
- (<span class="hljs-keyword">DEFAULT, <span class="hljs-string">‘1‘, <span class="hljs-string">‘小红‘, <span class="hljs-string">‘技术部‘, <span class="hljs-string">‘2015-11-02 14:49:54‘, <span class="hljs-string">‘2015-11-02 14:49:54‘);</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code>
Sequelize
会为主键id
设置DEFAULT
值来让数据库产生自增值,还将当前时间设置成了created_at
和updated_at
字段,非常方便。
Sequelize
:
- <code class="javascript"><span class="hljs-comment">// 方法1:操作对象属性(不会操作db),调用save后操作db
- user.nick = <span class="hljs-string">‘小白‘;
- user = <span class="hljs-keyword">yield user.save();
- <span class="hljs-built_in">console.log(user.get({<span class="hljs-string">‘plain‘: <span class="hljs-literal">true}));
- <span class="hljs-comment">// 方法2:直接update操作db
- user = <span class="hljs-keyword">yield user.update({
- <span class="hljs-string">‘nick‘: <span class="hljs-string">‘小白白‘
- });
- <span class="hljs-built_in">console.log(user.get({<span class="hljs-string">‘plain‘: <span class="hljs-literal">true}));</span></span></span></span></span></span></span></span></span></span></span></span></span></code>
SQL
:
- <code class="sql"><span class="hljs-keyword">UPDATE <span class="hljs-string">`users`
- <span class="hljs-keyword">SET <span class="hljs-string">`nick` = <span class="hljs-string">‘小白白‘, <span class="hljs-string">`updated_at` = <span class="hljs-string">‘2015-11-02 15:00:04‘
- <span class="hljs-keyword">WHERE <span class="hljs-string">`id` = <span class="hljs-number">1;</span></span></span></span></span></span></span></span></span></span></code>
更新操作时,Sequelize
将将当前时间设置成了updated_at
,非常方便。
如果想限制更新属性的白名单,可以这样写:
- <code class="javascript"><span class="hljs-comment">// 方法1
- user.emp_id = <span class="hljs-string">‘33‘;
- user.nick = <span class="hljs-string">‘小白‘;
- user = <span class="hljs-keyword">yield user.save({<span class="hljs-string">‘fields‘: [<span class="hljs-string">‘nick‘]});
- <span class="hljs-comment">// 方法2
- user = <span class="hljs-keyword">yield user.update(
- {<span class="hljs-string">‘emp_id‘: <span class="hljs-string">‘33‘, <span class="hljs-string">‘nick‘: <span class="hljs-string">‘小白‘},
- {<span class="hljs-string">‘fields‘: [<span class="hljs-string">‘nick‘]}
- });</span></span></span></span></span></span></span></span></span></span></span></span></span></span></code>
这样就只会更新nick
字段,而emp_id
会被忽略。这种方法在对表单提交过来的一大推数据中只更新某些属性的时候比较有用。
Sequelize
:
- <code class="javascript"><span class="hljs-keyword">yield user.destroy();</span></code>
SQL
:
- <code class="sql"><span class="hljs-keyword">DELETE <span class="hljs-keyword">FROM <span class="hljs-string">`users` <span class="hljs-keyword">WHERE <span class="hljs-string">`id` = <span class="hljs-number">1;</span></span></span></span></span></span></code>
这里有个特殊的地方是,如果我们开启了paranoid
(偏执)模式,destroy
的时候不会执行DELETE
语句,而是执行一个UPDATE
语句将deleted_at
字段设置为当前时间(一开始此字段值为NULL
)。我们可以使用user.destroy({force: true})
来强制删除,从而执行DELETE
语句进行物理删除。
Sequelize
:
- <code class="javascript"><span class="hljs-keyword">var users = <span class="hljs-keyword">yield User.findAll();
- <span class="hljs-built_in">console.log(users);</span></span></span></code>
SQL
:
- <code class="sql"><span class="hljs-keyword">SELECT <span class="hljs-string">`id`, <span class="hljs-string">`emp_id`, <span class="hljs-string">`nick`, <span class="hljs-string">`department`, <span class="hljs-string">`created_at`, <span class="hljs-string">`updated_at` <span class="hljs-keyword">FROM <span class="hljs-string">`users`;</span></span></span></span></span></span></span></span></span></code>
Sequelize
:
- <code class="javascript"><span class="hljs-keyword">var users = <span class="hljs-keyword">yield User.findAll({
- <span class="hljs-string">‘attributes‘: [<span class="hljs-string">‘emp_id‘, <span class="hljs-string">‘nick‘]
- });
- <span class="hljs-built_in">console.log(users);</span></span></span></span></span></span></code>
SQL
:
- <code class="sql"><span class="hljs-keyword">SELECT <span class="hljs-string">`emp_id`, <span class="hljs-string">`nick` <span class="hljs-keyword">FROM <span class="hljs-string">`users`;</span></span></span></span></span></code>
Sequelize
:
- <code class="javascript"><span class="hljs-keyword">var users = <span class="hljs-keyword">yield User.findAll({
- <span class="hljs-string">‘attributes‘: [
- <span class="hljs-string">‘emp_id‘, [<span class="hljs-string">‘nick‘, <span class="hljs-string">‘user_nick‘]
- ]
- });
- <span class="hljs-built_in">console.log(users);</span></span></span></span></span></span></span></code>
SQL
:
- <code class="sql"><span class="hljs-keyword">SELECT <span class="hljs-string">`emp_id`, <span class="hljs-string">`nick` <span class="hljs-keyword">AS <span class="hljs-string">`user_nick` <span class="hljs-keyword">FROM <span class="hljs-string">`users`;</span></span></span></span></span></span></span></code>
Sequelize
的where
配置项基本上完全支持了SQL
的where
子句的功能,非常强大。我们一步步来进行介绍。
Sequelize
:
- <code class="javascript"><span class="hljs-keyword">var users = <span class="hljs-keyword">yield User.findAll({
- <span class="hljs-string">‘where‘: {
- <span class="hljs-string">‘id‘: [<span class="hljs-number">1, <span class="hljs-number">2, <span class="hljs-number">3],
- <span class="hljs-string">‘nick‘: <span class="hljs-string">‘a‘,
- <span class="hljs-string">‘department‘: <span class="hljs-literal">null
- }
- });
- <span class="hljs-built_in">console.log(users);</span></span></span></span></span></span></span></span></span></span></span></span></code>
SQL
:
- <code class="sql"><span class="hljs-keyword">SELECT <span class="hljs-string">`id`, <span class="hljs-string">`emp_id`, <span class="hljs-string">`nick`, <span class="hljs-string">`department`, <span class="hljs-string">`created_at`, <span class="hljs-string">`updated_at`
- <span class="hljs-keyword">FROM <span class="hljs-string">`users` <span class="hljs-keyword">AS <span class="hljs-string">`user`
- <span class="hljs-keyword">WHERE
- <span class="hljs-string">`user`.<span class="hljs-string">`id` <span class="hljs-keyword">IN (<span class="hljs-number">1, <span class="hljs-number">2, <span class="hljs-number">3) <span class="hljs-keyword">AND
- <span class="hljs-string">`user`.<span class="hljs-string">`nick`=<span class="hljs-string">‘a‘ <span class="hljs-keyword">AND
- <span class="hljs-string">`user`.<span class="hljs-string">`department` <span class="hljs-keyword">IS <span class="hljs-literal">NULL;</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code>
可以看到,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
:
- <code class="javascript"><span class="hljs-keyword">var users = <span class="hljs-keyword">yield User.findAll({
- <span class="hljs-string">‘where‘: {
- <span class="hljs-string">‘id‘: {
- <span class="hljs-string">‘$eq‘: <span class="hljs-number">1, <span class="hljs-comment">// id = 1
- <span class="hljs-string">‘$ne‘: <span class="hljs-number">2, <span class="hljs-comment">// id != 2
- <span class="hljs-string">‘$gt‘: <span class="hljs-number">6, <span class="hljs-comment">// id > 6
- <span class="hljs-string">‘$gte‘: <span class="hljs-number">6, <span class="hljs-comment">// id >= 6
- <span class="hljs-string">‘$lt‘: <span class="hljs-number">10, <span class="hljs-comment">// id < 10
- <span class="hljs-string">‘$lte‘: <span class="hljs-number">10, <span class="hljs-comment">// id <= 10
- <span class="hljs-string">‘$between‘: [<span class="hljs-number">6, <span class="hljs-number">10], <span class="hljs-comment">// id BETWEEN 6 AND 10
- <span class="hljs-string">‘$notBetween‘: [<span class="hljs-number">11, <span class="hljs-number">15], <span class="hljs-comment">// id NOT BETWEEN 11 AND 15
- <span class="hljs-string">‘$in‘: [<span class="hljs-number">1, <span class="hljs-number">2], <span class="hljs-comment">// id IN (1, 2)
- <span class="hljs-string">‘$notIn‘: [<span class="hljs-number">3, <span class="hljs-number">4] <span class="hljs-comment">// id NOT IN (3, 4)
- },
- <span class="hljs-string">‘nick‘: {
- <span class="hljs-string">‘$like‘: <span class="hljs-string">‘%a%‘, <span class="hljs-comment">// nick LIKE ‘%a%‘
- <span class="hljs-string">‘$notLike‘: <span class="hljs-string">‘%a‘ <span class="hljs-comment">// nick NOT LIKE ‘%a‘
- },
- <span class="hljs-string">‘updated_at‘: {
- <span class="hljs-string">‘$eq‘: <span class="hljs-literal">null, <span class="hljs-comment">// updated_at IS NULL
- <span class="hljs-string">‘$ne‘: <span class="hljs-literal">null <span class="hljs-comment">// created_at IS NOT NULL
- }
- }
- });
- </span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code>
SQL
:
- <code class="sql"><span class="hljs-keyword">SELECT <span class="hljs-string">`id`, <span class="hljs-string">`emp_id`, <span class="hljs-string">`nick`, <span class="hljs-string">`department`, <span class="hljs-string">`created_at`, <span class="hljs-string">`updated_at`
- <span class="hljs-keyword">FROM <span class="hljs-string">`users` <span class="hljs-keyword">AS <span class="hljs-string">`user`
- <span class="hljs-keyword">WHERE
- (
- <span class="hljs-string">`user`.<span class="hljs-string">`id` = <span class="hljs-number">1 <span class="hljs-keyword">AND
- <span class="hljs-string">`user`.<span class="hljs-string">`id` != <span class="hljs-number">2 <span class="hljs-keyword">AND
- <span class="hljs-string">`user`.<span class="hljs-string">`id` > <span class="hljs-number">6 <span class="hljs-keyword">AND
- <span class="hljs-string">`user`.<span class="hljs-string">`id` >= <span class="hljs-number">6 <span class="hljs-keyword">AND
- <span class="hljs-string">`user`.<span class="hljs-string">`id` < <span class="hljs-number">10 <span class="hljs-keyword">AND
- <span class="hljs-string">`user`.<span class="hljs-string">`id` <= <span class="hljs-number">10 <span class="hljs-keyword">AND
- <span class="hljs-string">`user`.<span class="hljs-string">`id` <span class="hljs-keyword">BETWEEN <span class="hljs-number">6 <span class="hljs-keyword">AND <span class="hljs-number">10 <span class="hljs-keyword">AND
- <span class="hljs-string">`user`.<span class="hljs-string">`id` <span class="hljs-keyword">NOT <span class="hljs-keyword">BETWEEN <span class="hljs-number">11 <span class="hljs-keyword">AND <span class="hljs-number">15 <span class="hljs-keyword">AND
- <span class="hljs-string">`user`.<span class="hljs-string">`id` <span class="hljs-keyword">IN (<span class="hljs-number">1, <span class="hljs-number">2) <span class="hljs-keyword">AND
- <span class="hljs-string">`user`.<span class="hljs-string">`id` <span class="hljs-keyword">NOT <span class="hljs-keyword">IN (<span class="hljs-number">3, <span class="hljs-number">4)
- )
- <span class="hljs-keyword">AND
- (
- <span class="hljs-string">`user`.<span class="hljs-string">`nick` <span class="hljs-keyword">LIKE <span class="hljs-string">‘%a%‘ <span class="hljs-keyword">AND
- <span class="hljs-string">`user`.<span class="hljs-string">`nick` <span class="hljs-keyword">NOT <span class="hljs-keyword">LIKE <span class="hljs-string">‘%a‘
- )
- <span class="hljs-keyword">AND
- (
- <span class="hljs-string">`user`.<span class="hljs-string">`updated_at` <span class="hljs-keyword">IS <span class="hljs-literal">NULL <span class="hljs-keyword">AND
- <span class="hljs-string">`user`.<span class="hljs-string">`updated_at` <span class="hljs-keyword">IS <span class="hljs-keyword">NOT <span class="hljs-literal">NULL
- );</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code>
这里我们发现,其实相等条件k: v
这种写法是操作符写法k: {$eq: v}
的简写。而要实现不等条件就必须使用操作符写法k: {$ne: v}
。
上面我们说的条件查询,都是AND
查询,Sequelize
同时也支持OR
、NOT
、甚至多种条件的联合查询。
Sequelize
:
- <code class="javascript"><span class="hljs-keyword">var users = <span class="hljs-keyword">yield User.findAll({
- <span class="hljs-string">‘where‘: {
- <span class="hljs-string">‘$and‘: [
- {<span class="hljs-string">‘id‘: [<span class="hljs-number">1, <span class="hljs-number">2]},
- {<span class="hljs-string">‘nick‘: <span class="hljs-literal">null}
- ]
- }
- });</span></span></span></span></span></span></span></span></span></code>
SQL
:
- <code class="sql"><span class="hljs-keyword">SELECT <span class="hljs-string">`id`, <span class="hljs-string">`emp_id`, <span class="hljs-string">`nick`, <span class="hljs-string">`department`, <span class="hljs-string">`created_at`, <span class="hljs-string">`updated_at`
- <span class="hljs-keyword">FROM <span class="hljs-string">`users` <span class="hljs-keyword">AS <span class="hljs-string">`user`
- <span class="hljs-keyword">WHERE
- (
- <span class="hljs-string">`user`.<span class="hljs-string">`id` <span class="hljs-keyword">IN (<span class="hljs-number">1, <span class="hljs-number">2) <span class="hljs-keyword">AND
- <span class="hljs-string">`user`.<span class="hljs-string">`nick` <span class="hljs-keyword">IS <span class="hljs-literal">NULL
- );</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code>
Sequelize
:
- <code class="javascript"><span class="hljs-keyword">var users = <span class="hljs-keyword">yield User.findAll({
- <span class="hljs-string">‘where‘: {
- <span class="hljs-string">‘$or‘: [
- {<span class="hljs-string">‘id‘: [<span class="hljs-number">1, <span class="hljs-number">2]},
- {<span class="hljs-string">‘nick‘: <span class="hljs-literal">null}
- ]
- }
- });</span></span></span></span></span></span></span></span></span></code>
SQL
:
- <code class="sql"><span class="hljs-keyword">SELECT <span class="hljs-string">`id`, <span class="hljs-string">`emp_id`, <span class="hljs-string">`nick`, <span class="hljs-string">`department`, <span class="hljs-string">`created_at`, <span class="hljs-string">`updated_at`
- <span class="hljs-keyword">FROM <span class="hljs-string">`users` <span class="hljs-keyword">AS <span class="hljs-string">`user`
- <span class="hljs-keyword">WHERE
- (
- <span class="hljs-string">`user`.<span class="hljs-string">`id` <span class="hljs-keyword">IN (<span class="hljs-number">1, <span class="hljs-number">2) <span class="hljs-keyword">OR
- <span class="hljs-string">`user`.<span class="hljs-string">`nick` <span class="hljs-keyword">IS <span class="hljs-literal">NULL
- );</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code>
Sequelize
:
- <code class="javascript"><span class="hljs-keyword">var users = <span class="hljs-keyword">yield User.findAll({
- <span class="hljs-string">‘where‘: {
- <span class="hljs-string">‘$not‘: [
- {<span class="hljs-string">‘id‘: [<span class="hljs-number">1, <span class="hljs-number">2]},
- {<span class="hljs-string">‘nick‘: <span class="hljs-literal">null}
- ]
- }
- });</span></span></span></span></span></span></span></span></span></code>
SQL
:
- <code class="sql"><span class="hljs-keyword">SELECT <span class="hljs-string">`id`, <span class="hljs-string">`emp_id`, <span class="hljs-string">`nick`, <span class="hljs-string">`department`, <span class="hljs-string">`created_at`, <span class="hljs-string">`updated_at`
- <span class="hljs-keyword">FROM <span class="hljs-string">`users` <span class="hljs-keyword">AS <span class="hljs-string">`user`
- <span class="hljs-keyword">WHERE
- <span class="hljs-keyword">NOT (
- <span class="hljs-string">`user`.<span class="hljs-string">`id` <span class="hljs-keyword">IN (<span class="hljs-number">1, <span class="hljs-number">2) <span class="hljs-keyword">AND
- <span class="hljs-string">`user`.<span class="hljs-string">`nick` <span class="hljs-keyword">IS <span class="hljs-literal">NULL
- );</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code>
我们这里做个总结。Sequelize
对where
配置的转换规则的伪代码大概如下:
- <code class="javascript"><span class="hljs-function"><span class="hljs-keyword">function <span class="hljs-title">translate<span class="hljs-params">(where) {
- <span class="hljs-keyword">for (k, v of where) {
- <span class="hljs-keyword">if (k == 表字段) {
- <span class="hljs-comment">// 先统一转为操作符形式
- <span class="hljs-keyword">if (v == 基本值) { <span class="hljs-comment">// k: ‘xxx‘
- v = {<span class="hljs-string">‘$eq‘: v};
- }
- <span class="hljs-keyword">if (v == 数组) { <span class="hljs-comment">// k: [1, 2, 3]
- v = {<span class="hljs-string">‘$in‘: v};
- }
- <span class="hljs-comment">// 操作符转换
- <span class="hljs-keyword">for (opk, opv of v) {
- <span class="hljs-comment">// op将opk转换对应的SQL表示
- => k + op(opk, opv) + AND;
- }
- }
- <span class="hljs-comment">// 逻辑操作符处理
- <span class="hljs-keyword">if (k == <span class="hljs-string">‘$and‘) {
- <span class="hljs-keyword">for (item <span class="hljs-keyword">in v) {
- => translate(item) + AND;
- }
- }
- <span class="hljs-keyword">if (k == <span class="hljs-string">‘$or‘) {
- <span class="hljs-keyword">for (item <span class="hljs-keyword">in v) {
- => translate(item) + OR;
- }
- }
- <span class="hljs-keyword">if (k == <span class="hljs-string">‘$not‘) {
- NOT +
- <span class="hljs-keyword">for (item <span class="hljs-keyword">in v) {
- => translate(item) + AND;
- }
- }
- }
- <span class="hljs-function"><span class="hljs-keyword">function <span class="hljs-title">op<span class="hljs-params">(opk, opv) {
- <span class="hljs-keyword">switch (opk) {
- <span class="hljs-keyword">case $eq => (<span class="hljs-string">‘=‘ + opv) || <span class="hljs-string">‘IS NULL‘;
- <span class="hljs-keyword">case $ne => (<span class="hljs-string">‘!=‘ + opv) || <span class="hljs-string">‘IS NOT NULL‘;
- <span class="hljs-keyword">case $gt => <span class="hljs-string">‘>‘ + opv;
- <span class="hljs-keyword">case $lt => <span class="hljs-string">‘<‘ + opv;
- <span class="hljs-keyword">case $gte => <span class="hljs-string">‘>=‘ + opv;
- <span class="hljs-keyword">case $lte => <span class="hljs-string">‘<=‘ + opv;
- <span class="hljs-keyword">case $between => <span class="hljs-string">‘BETWEEN ‘ + opv[<span class="hljs-number">0] + <span class="hljs-string">‘ AND ‘ + opv[<span class="hljs-number">1];
- <span class="hljs-keyword">case $notBetween => <span class="hljs-string">‘NOT BETWEEN ‘ + opv[<span class="hljs-number">0] + <span class="hljs-string">‘ AND ‘ + opv[<span class="hljs-number">1];
- <span class="hljs-keyword">case $<span class="hljs-keyword">in => <span class="hljs-string">‘IN (‘ + opv.join(<span class="hljs-string">‘,‘) + <span class="hljs-string">‘)‘;
- <span class="hljs-keyword">case $notIn => <span class="hljs-string">‘NOT IN (‘ + opv.join(<span class="hljs-string">‘,‘) + <span class="hljs-string">‘)‘;
- <span class="hljs-keyword">case $like => <span class="hljs-string">‘LIKE ‘ + opv;
- <span class="hljs-keyword">case $notLike => <span class="hljs-string">‘NOT LIKE ‘ + opv;
- }
- }
- }
- </span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code>
我们看一个复杂例子,基本上就是按上述流程来进行转换。
Sequelize
:
- <code class="javascript"><span class="hljs-keyword">var users = <span class="hljs-keyword">yield User.findAll({
- <span class="hljs-string">‘where‘: {
- <span class="hljs-string">‘id‘: [<span class="hljs-number">3, <span class="hljs-number">4],
- <span class="hljs-string">‘$not‘: [
- {
- <span class="hljs-string">‘id‘: {
- <span class="hljs-string">‘$in‘: [<span class="hljs-number">1, <span class="hljs-number">2]
- }
- },
- {
- <span class="hljs-string">‘$or‘: [
- {<span class="hljs-string">‘id‘: [<span class="hljs-number">1, <span class="hljs-number">2]},
- {<span class="hljs-string">‘nick‘: <span class="hljs-literal">null}
- ]
- }
- ],
- <span class="hljs-string">‘$and‘: [
- {<span class="hljs-string">‘id‘: [<span class="hljs-number">1, <span class="hljs-number">2]},
- {<span class="hljs-string">‘nick‘: <span class="hljs-literal">null}
- ],
- <span class="hljs-string">‘$or‘: [
- {<span class="hljs-string">‘id‘: [<span class="hljs-number">1, <span class="hljs-number">2]},
- {<span class="hljs-string">‘nick‘: <span class="hljs-literal">null}
- ]
- }
- });</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code>
SQL
:
- <code class="sql"><span class="hljs-keyword">SELECT <span class="hljs-string">`id`, <span class="hljs-string">`emp_id`, <span class="hljs-string">`nick`, <span class="hljs-string">`department`, <span class="hljs-string">`created_at`, <span class="hljs-string">`updated_at`
- <span class="hljs-keyword">FROM <span class="hljs-string">`users` <span class="hljs-keyword">AS <span class="hljs-string">`user`
- <span class="hljs-keyword">WHERE
- <span class="hljs-string">`user`.<span class="hljs-string">`id` <span class="hljs-keyword">IN (<span class="hljs-number">3, <span class="hljs-number">4)
- <span class="hljs-keyword">AND
- <span class="hljs-keyword">NOT
- (
- <span class="hljs-string">`user`.<span class="hljs-string">`id` <span class="hljs-keyword">IN (<span class="hljs-number">1, <span class="hljs-number">2)
- <span class="hljs-keyword">AND
- (<span class="hljs-string">`user`.<span class="hljs-string">`id` <span class="hljs-keyword">IN (<span class="hljs-number">1, <span class="hljs-number">2) <span class="hljs-keyword">OR <span class="hljs-string">`user`.<span class="hljs-string">`nick` <span class="hljs-keyword">IS <span class="hljs-literal">NULL)
- )
- <span class="hljs-keyword">AND
- (
- <span class="hljs-string">`user`.<span class="hljs-string">`id` <span class="hljs-keyword">IN (<span class="hljs-number">1, <span class="hljs-number">2) <span class="hljs-keyword">AND <span class="hljs-string">`user`.<span class="hljs-string">`nick` <span class="hljs-keyword">IS <span class="hljs-literal">NULL
- )
- <span class="hljs-keyword">AND
- (
- <span class="hljs-string">`user`.<span class="hljs-string">`id` <span class="hljs-keyword">IN (<span class="hljs-number">1, <span class="hljs-number">2) <span class="hljs-keyword">OR <span class="hljs-string">`user`.<span class="hljs-string">`nick` <span class="hljs-keyword">IS <span class="hljs-literal">NULL
- );</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code>
Sequelize
:
- <code class="javascript"><span class="hljs-keyword">var users = <span class="hljs-keyword">yield User.findAll({
- <span class="hljs-string">‘order‘: [
- [<span class="hljs-string">‘id‘, <span class="hljs-string">‘DESC‘],
- [<span class="hljs-string">‘nick‘]
- ]
- });</span></span></span></span></span></span></code>
SQL
:
- <code class="sql"><span class="hljs-keyword">SELECT <span class="hljs-string">`id`, <span class="hljs-string">`emp_id`, <span class="hljs-string">`nick`, <span class="hljs-string">`department`, <span class="hljs-string">`created_at`, <span class="hljs-string">`updated_at`
- <span class="hljs-keyword">FROM <span class="hljs-string">`users` <span class="hljs-keyword">AS <span class="hljs-string">`user`
- <span class="hljs-keyword">ORDER <span class="hljs-keyword">BY <span class="hljs-string">`user`.<span class="hljs-string">`id` <span class="hljs-keyword">DESC, <span class="hljs-string">`user`.<span class="hljs-string">`nick`;</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code>
Sequelize
:
- <code class="javascript"><span class="hljs-keyword">var countPerPage = <span class="hljs-number">20, currentPage = <span class="hljs-number">5;
- <span class="hljs-keyword">var users = <span class="hljs-keyword">yield User.findAll({
- <span class="hljs-string">‘limit‘: countPerPage, <span class="hljs-comment">// 每页多少条
- <span class="hljs-string">‘offset‘: countPerPage * (currentPage - <span class="hljs-number">1) <span class="hljs-comment">// 跳过多少条
- });</span></span></span></span></span></span></span></span></span></span></code>
SQL
:
- <code class="sql"><span class="hljs-keyword">SELECT <span class="hljs-string">`id`, <span class="hljs-string">`emp_id`, <span class="hljs-string">`nick`, <span class="hljs-string">`department`, <span class="hljs-string">`created_at`, <span class="hljs-string">`updated_at`
- <span class="hljs-keyword">FROM <span class="hljs-string">`users` <span class="hljs-keyword">AS <span class="hljs-string">`user`
- <span class="hljs-keyword">LIMIT <span class="hljs-number">80, <span class="hljs-number">20;</span></span></span></span></span></span></span></span></span></span></span></span></span></span></code>
Sequelize
:
- <code class="javascript">user = <span class="hljs-keyword">yield User.findById(<span class="hljs-number">1);
- user = <span class="hljs-keyword">yield User.findOne({
- <span class="hljs-string">‘where‘: {<span class="hljs-string">‘nick‘: <span class="hljs-string">‘a‘}
- });</span></span></span></span></span></span></code>
SQL
:
- <code class="sql"><span class="hljs-operator"><span class="hljs-keyword">SELECT <span class="hljs-string">`id`, <span class="hljs-string">`emp_id`, <span class="hljs-string">`nick`, <span class="hljs-string">`department`, <span class="hljs-string">`created_at`, <span class="hljs-string">`updated_at`
- <span class="hljs-keyword">FROM <span class="hljs-string">`users` <span class="hljs-keyword">AS <span class="hljs-string">`user`
- <span class="hljs-keyword">WHERE <span class="hljs-string">`user`.<span class="hljs-string">`id` = <span class="hljs-number">1 <span class="hljs-keyword">LIMIT <span class="hljs-number">1;
- <span class="hljs-operator"><span class="hljs-keyword">SELECT <span class="hljs-string">`id`, <span class="hljs-string">`emp_id`, <span class="hljs-string">`nick`, <span class="hljs-string">`department`, <span class="hljs-string">`created_at`, <span class="hljs-string">`updated_at`
- <span class="hljs-keyword">FROM <span class="hljs-string">`users` <span class="hljs-keyword">AS <span class="hljs-string">`user`
- <span class="hljs-keyword">WHERE <span class="hljs-string">`user`.<span class="hljs-string">`nick` = <span class="hljs-string">‘a‘ <span class="hljs-keyword">LIMIT <span class="hljs-number">1;</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code>
Sequelize
:
- <code class="javascript"><span class="hljs-keyword">var result = <span class="hljs-keyword">yield User.findAndCountAll({
- <span class="hljs-string">‘limit‘: <span class="hljs-number">20,
- <span class="hljs-string">‘offset‘: <span class="hljs-number">0
- });
- <span class="hljs-built_in">console.log(result);</span></span></span></span></span></span></span></code>
SQL
:
- <code class="sql"><span class="hljs-operator"><span class="hljs-keyword">SELECT <span class="hljs-keyword">count(*) <span class="hljs-keyword">AS <span class="hljs-string">`count` <span class="hljs-keyword">FROM <span class="hljs-string">`users` <span class="hljs-keyword">AS <span class="hljs-string">`user`;
- <span class="hljs-operator"><span class="hljs-keyword">SELECT <span class="hljs-string">`id`, <span class="hljs-string">`emp_id`, <span class="hljs-string">`nick`, <span class="hljs-string">`department`, <span class="hljs-string">`created_at`, <span class="hljs-string">`updated_at`
- <span class="hljs-keyword">FROM <span class="hljs-string">`users` <span class="hljs-keyword">AS <span class="hljs-string">`user`
- <span class="hljs-keyword">LIMIT <span class="hljs-number">20;</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code>
这个方法会执行2个SQL
,返回的result
对象将包含2个字段:result.count
是数据总数,result.rows
是符合查询条件的所有数据。
Sequelize
:
- <code class="javascript"><span class="hljs-keyword">var users = <span class="hljs-keyword">yield User.bulkCreate(
- [
- {<span class="hljs-string">‘emp_id‘: <span class="hljs-string">‘a‘, <span class="hljs-string">‘nick‘: <span class="hljs-string">‘a‘},
- {<span class="hljs-string">‘emp_id‘: <span class="hljs-string">‘b‘, <span class="hljs-string">‘nick‘: <span class="hljs-string">‘b‘},
- {<span class="hljs-string">‘emp_id‘: <span class="hljs-string">‘c‘, <span class="hljs-string">‘nick‘: <span class="hljs-string">‘c‘}
- ]
- );</span></span></span></span></span></span></span></span></span></span></span></span></span></span></code>
SQL
:
- <code class="sql"><span class="hljs-keyword">INSERT <span class="hljs-keyword">INTO <span class="hljs-string">`users`
- (<span class="hljs-string">`id`,<span class="hljs-string">`emp_id`,<span class="hljs-string">`nick`,<span class="hljs-string">`created_at`,<span class="hljs-string">`updated_at`)
- <span class="hljs-keyword">VALUES
- (<span class="hljs-literal">NULL,<span class="hljs-string">‘a‘,<span class="hljs-string">‘a‘,<span class="hljs-string">‘2015-11-03 02:43:30‘,<span class="hljs-string">‘2015-11-03 02:43:30‘),
- (<span class="hljs-literal">NULL,<span class="hljs-string">‘b‘,<span class="hljs-string">‘b‘,<span class="hljs-string">‘2015-11-03 02:43:30‘,<span class="hljs-string">‘2015-11-03 02:43:30‘),
- (<span class="hljs-literal">NULL,<span class="hljs-string">‘c‘,<span class="hljs-string">‘c‘,<span class="hljs-string">‘2015-11-03 02:43:30‘,<span class="hljs-string">‘2015-11-03 02:43:30‘);</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code>
这里需要注意,返回的users
数组里面每个对象的id
值会是null
。如果需要id
值,可以重新取下数据。
Sequelize
:
- <code class="javascript"><span class="hljs-keyword">var affectedRows = <span class="hljs-keyword">yield User.update(
- {<span class="hljs-string">‘nick‘: <span class="hljs-string">‘hhhh‘},
- {
- <span class="hljs-string">‘where‘: {
- <span class="hljs-string">‘id‘: [<span class="hljs-number">2, <span class="hljs-number">3, <span class="hljs-number">4]
- }
- }
- );</span></span></span></span></span></span></span></span></span></code>
SQL
:
- <code class="sql"><span class="hljs-keyword">UPDATE <span class="hljs-string">`users`
- <span class="hljs-keyword">SET <span class="hljs-string">`nick`=<span class="hljs-string">‘hhhh‘,<span class="hljs-string">`updated_at`=<span class="hljs-string">‘2015-11-03 02:51:05‘
- <span class="hljs-keyword">WHERE <span class="hljs-string">`id` <span class="hljs-keyword">IN (<span class="hljs-number">2, <span class="hljs-number">3, <span class="hljs-number">4);</span></span></span></span></span></span></span></span></span></span></span></span></span></code>
这里返回的affectedRows
其实是一个数组,里面只有一个元素,表示更新的数据条数(看起来像是Sequelize
的一个bug
)。
Sequelize
:
- <code class="javascript"><span class="hljs-keyword">var affectedRows = <span class="hljs-keyword">yield User.destroy({
- <span class="hljs-string">‘where‘: {<span class="hljs-string">‘id‘: [<span class="hljs-number">2, <span class="hljs-number">3, <span class="hljs-number">4]}
- });</span></span></span></span></span></span></span></code>
SQL
:
- <code class="sql"><span class="hljs-keyword">DELETE <span class="hljs-keyword">FROM <span class="hljs-string">`users` <span class="hljs-keyword">WHERE <span class="hljs-string">`id` <span class="hljs-keyword">IN (<span class="hljs-number">2, <span class="hljs-number">3, <span class="hljs-number">4);</span></span></span></span></span></span></span></span></span></code>
这里返回的affectedRows
是一个数字,表示删除的数据条数。
关系一般有三种:一对一、一对多、多对多。Sequelize
提供了清晰易用的接口来定义关系、进行表间的操作。
当说到关系查询时,一般会需要获取多张表的数据。有建议用连表查询join
的,有不建议的。我的看法是,join
查询这种黑科技在数据量小的情况下可以使用,基本没有什么影响,数据量大的时候,join
的性能可能会是硬伤,应该尽量避免,可以分别根据索引取单表数据然后在应用层对数据进行join
、merge
。当然,查询时一定要分页,不要findAll
。
Sequelize
:
- <code class="javascript"><span class="hljs-keyword">var User = sequelize.define(<span class="hljs-string">‘user‘,
- {
- <span class="hljs-string">‘emp_id‘: {
- <span class="hljs-string">‘type‘: Sequelize.CHAR(<span class="hljs-number">10),
- <span class="hljs-string">‘allowNull‘: <span class="hljs-literal">false,
- <span class="hljs-string">‘unique‘: <span class="hljs-literal">true
- }
- }
- );
- <span class="hljs-keyword">var Account = sequelize.define(<span class="hljs-string">‘account‘,
- {
- <span class="hljs-string">‘email‘: {
- <span class="hljs-string">‘type‘: Sequelize.CHAR(<span class="hljs-number">20),
- <span class="hljs-string">‘allowNull‘: <span class="hljs-literal">false
- }
- }
- );
- <span class="hljs-comment">/*
- * User的实例对象将拥有getAccount、setAccount、addAccount方法
- */
- User.hasOne(Account);
- <span class="hljs-comment">/*
- * Account的实例对象将拥有getUser、setUser、addUser方法
- */
- Account.belongsTo(User);</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code>
SQL
:
- <code class="sql"><span class="hljs-operator"><span class="hljs-keyword">CREATE <span class="hljs-keyword">TABLE <span class="hljs-keyword">IF <span class="hljs-keyword">NOT <span class="hljs-keyword">EXISTS <span class="hljs-string">`users` (
- <span class="hljs-string">`id` <span class="hljs-built_in">INTEGER <span class="hljs-keyword">NOT <span class="hljs-literal">NULL auto_increment ,
- <span class="hljs-string">`emp_id` <span class="hljs-built_in">CHAR(<span class="hljs-number">10) <span class="hljs-keyword">NOT <span class="hljs-literal">NULL <span class="hljs-keyword">UNIQUE,
- <span class="hljs-string">`created_at` DATETIME <span class="hljs-keyword">NOT <span class="hljs-literal">NULL,
- <span class="hljs-string">`updated_at` DATETIME <span class="hljs-keyword">NOT <span class="hljs-literal">NULL,
- <span class="hljs-keyword">PRIMARY <span class="hljs-keyword">KEY (<span class="hljs-string">`id`)
- ) <span class="hljs-keyword">ENGINE=<span class="hljs-keyword">InnoDB;
- <span class="hljs-operator"><span class="hljs-keyword">CREATE <span class="hljs-keyword">TABLE <span class="hljs-keyword">IF <span class="hljs-keyword">NOT <span class="hljs-keyword">EXISTS <span class="hljs-string">`accounts` (
- <span class="hljs-string">`id` <span class="hljs-built_in">INTEGER <span class="hljs-keyword">NOT <span class="hljs-literal">NULL auto_increment ,
- <span class="hljs-string">`email` <span class="hljs-built_in">CHAR(<span class="hljs-number">20) <span class="hljs-keyword">NOT <span class="hljs-literal">NULL,
- <span class="hljs-string">`created_at` DATETIME <span class="hljs-keyword">NOT <span class="hljs-literal">NULL,
- <span class="hljs-string">`updated_at` DATETIME <span class="hljs-keyword">NOT <span class="hljs-literal">NULL,
- <span class="hljs-string">`user_id` <span class="hljs-built_in">INTEGER,
- <span class="hljs-keyword">PRIMARY <span class="hljs-keyword">KEY (<span class="hljs-string">`id`),
- <span class="hljs-keyword">FOREIGN <span class="hljs-keyword">KEY (<span class="hljs-string">`user_id`) <span class="hljs-keyword">REFERENCES <span class="hljs-string">`users` (<span class="hljs-string">`id`) <span class="hljs-keyword">ON <span class="hljs-keyword">DELETE <span class="hljs-keyword">SET <span class="hljs-literal">NULL <span class="hljs-keyword">ON <span class="hljs-keyword">UPDATE <span class="hljs-keyword">CASCADE
- ) <span class="hljs-keyword">ENGINE=<span class="hljs-keyword">InnoDB;</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code>
可以看到,这种关系中外键user_id
加在了Account
上。另外,Sequelize
还给我们生成了外键约束。
一般来说,外键约束在有些自己定制的数据库系统里面是禁止的,因为会带来一些性能问题。所以,建表的SQL
一般就去掉约束,同时给外键加一个索引(加速查询),数据的一致性就靠应用层来保证了。
Sequelize
:
- <code class="javascript"><span class="hljs-keyword">var user = <span class="hljs-keyword">yield User.create({<span class="hljs-string">‘emp_id‘: <span class="hljs-string">‘1‘});
- <span class="hljs-keyword">var account = user.createAccount({<span class="hljs-string">‘email‘: <span class="hljs-string">‘a‘});
- <span class="hljs-built_in">console.log(account.get({<span class="hljs-string">‘plain‘: <span class="hljs-literal">true}));</span></span></span></span></span></span></span></span></span></span></code>
SQL
:
- <code class="sql"><span class="hljs-operator"><span class="hljs-keyword">INSERT <span class="hljs-keyword">INTO <span class="hljs-string">`users`
- (<span class="hljs-string">`id`,<span class="hljs-string">`emp_id`,<span class="hljs-string">`updated_at`,<span class="hljs-string">`created_at`)
- <span class="hljs-keyword">VALUES
- (<span class="hljs-keyword">DEFAULT,<span class="hljs-string">‘1‘,<span class="hljs-string">‘2015-11-03 06:24:53‘,<span class="hljs-string">‘2015-11-03 06:24:53‘);
- <span class="hljs-operator"><span class="hljs-keyword">INSERT <span class="hljs-keyword">INTO <span class="hljs-string">`accounts`
- (<span class="hljs-string">`id`,<span class="hljs-string">`email`,<span class="hljs-string">`user_id`,<span class="hljs-string">`updated_at`,<span class="hljs-string">`created_at`)
- <span class="hljs-keyword">VALUES
- (<span class="hljs-keyword">DEFAULT,<span class="hljs-string">‘a‘,<span class="hljs-number">1,<span class="hljs-string">‘2015-11-03 06:24:53‘,<span class="hljs-string">‘2015-11-03 06:24:53‘);</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code>
SQL
执行逻辑是:
使用对应的的user_id
作为外键在accounts
表里插入一条数据。
Sequelize
:
- <code class="javascript"><span class="hljs-keyword">var anotherAccount = <span class="hljs-keyword">yield Account.create({<span class="hljs-string">‘email‘: <span class="hljs-string">‘b‘});
- <span class="hljs-built_in">console.log(anotherAccount);
- anotherAccount = <span class="hljs-keyword">yield user.setAccount(anotherAccount);
- <span class="hljs-built_in">console.log(anotherAccount);</span></span></span></span></span></span></span></code>
SQL
:
- <code class="sql"><span class="hljs-operator"><span class="hljs-keyword">INSERT <span class="hljs-keyword">INTO <span class="hljs-string">`accounts`
- (<span class="hljs-string">`id`,<span class="hljs-string">`email`,<span class="hljs-string">`updated_at`,<span class="hljs-string">`created_at`)
- <span class="hljs-keyword">VALUES
- (<span class="hljs-keyword">DEFAULT,<span class="hljs-string">‘b‘,<span class="hljs-string">‘2015-11-03 06:37:14‘,<span class="hljs-string">‘2015-11-03 06:37:14‘);
- <span class="hljs-operator"><span class="hljs-keyword">SELECT <span class="hljs-string">`id`, <span class="hljs-string">`email`, <span class="hljs-string">`created_at`, <span class="hljs-string">`updated_at`, <span class="hljs-string">`user_id`
- <span class="hljs-keyword">FROM <span class="hljs-string">`accounts` <span class="hljs-keyword">AS <span class="hljs-string">`account` <span class="hljs-keyword">WHERE (<span class="hljs-string">`account`.<span class="hljs-string">`user_id` = <span class="hljs-number">1);
- <span class="hljs-operator"><span class="hljs-keyword">UPDATE <span class="hljs-string">`accounts` <span class="hljs-keyword">SET <span class="hljs-string">`user_id`=<span class="hljs-literal">NULL,<span class="hljs-string">`updated_at`=<span class="hljs-string">‘2015-11-03 06:37:14‘ <span class="hljs-keyword">WHERE <span class="hljs-string">`id` = <span class="hljs-number">1;
- <span class="hljs-operator"><span class="hljs-keyword">UPDATE <span class="hljs-string">`accounts` <span class="hljs-keyword">SET <span class="hljs-string">`user_id`=<span class="hljs-number">1,<span class="hljs-string">`updated_at`=<span class="hljs-string">‘2015-11-03 06:37:14‘ <span class="hljs-keyword">WHERE <span class="hljs-string">`id` = <span class="hljs-number">2;</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code>
SQL
执行逻辑是:
插入一条account
数据,此时外键user_id
是空的,还没有关联user
找出当前user
所关联的account
并将其user_id
置为`NUL(为了保证一对一关系)
设置新的acount
的外键user_id
为user
的属性id
,生成关系
Sequelize
:
- <code class="javascript"><span class="hljs-keyword">yield user.setAccount(<span class="hljs-literal">null);</span></span></code>
SQL
:
- <code class="sql"><span class="hljs-operator"><span class="hljs-keyword">SELECT <span class="hljs-string">`id`, <span class="hljs-string">`email`, <span class="hljs-string">`created_at`, <span class="hljs-string">`updated_at`, <span class="hljs-string">`user_id`
- <span class="hljs-keyword">FROM <span class="hljs-string">`accounts` <span class="hljs-keyword">AS <span class="hljs-string">`account`
- <span class="hljs-keyword">WHERE (<span class="hljs-string">`account`.<span class="hljs-string">`user_id` = <span class="hljs-number">1);
- <span class="hljs-operator"><span class="hljs-keyword">UPDATE <span class="hljs-string">`accounts`
- <span class="hljs-keyword">SET <span class="hljs-string">`user_id`=<span class="hljs-literal">NULL,<span class="hljs-string">`updated_at`=<span class="hljs-string">‘2015-11-04 00:11:35‘
- <span class="hljs-keyword">WHERE <span class="hljs-string">`id` = <span class="hljs-number">1;</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code>
这里的删除实际上只是“切断”关系,并不会真正的物理删除记录。
SQL
执行逻辑是:
找出user
所关联的account
数据
将其外键user_id
设置为NULL
,完成关系的“切断”
Sequelize
:
- <code class="javascript"><span class="hljs-keyword">var account = <span class="hljs-keyword">yield user.getAccount();
- <span class="hljs-built_in">console.log(account);</span></span></span></code>
SQL
:
- <code class="sql"><span class="hljs-keyword">SELECT <span class="hljs-string">`id`, <span class="hljs-string">`email`, <span class="hljs-string">`created_at`, <span class="hljs-string">`updated_at`, <span class="hljs-string">`user_id`
- <span class="hljs-keyword">FROM <span class="hljs-string">`accounts` <span class="hljs-keyword">AS <span class="hljs-string">`account`
- <span class="hljs-keyword">WHERE (<span class="hljs-string">`account`.<span class="hljs-string">`user_id` = <span class="hljs-number">1);</span></span></span></span></span></span></span></span></span></span></span></span></span></span></code>
这里就是调用user
的getAccount
方法,根据外键来获取对应的account
。
但是其实我们用面向对象的思维来思考应该是获取user
的时候就能通过user.account
的方式来访问account
对象。这可以通过Sequelize
的eager loading
(急加载,和懒加载相反)来实现。
eager loading
的含义是说,取一个模型的时候,同时也把相关的模型数据也给我取过来(我很着急,不能按默认那种取一个模型就取一个模型的方式,我还要更多)。方法如下:
Sequelize
:
- <code class="javascript"><span class="hljs-keyword">var user = <span class="hljs-keyword">yield User.findById(<span class="hljs-number">1, {
- <span class="hljs-string">‘include‘: [Account]
- });
- <span class="hljs-built_in">console.log(user.get({<span class="hljs-string">‘plain‘: <span class="hljs-literal">true}));
- <span class="hljs-comment">/*
- * 输出类似:
- { id: 1,
- emp_id: ‘1‘,
- created_at: Tue Nov 03 2015 15:25:27 GMT+0800 (CST),
- updated_at: Tue Nov 03 2015 15:25:27 GMT+0800 (CST),
- account:
- { id: 2,
- email: ‘b‘,
- created_at: Tue Nov 03 2015 15:25:27 GMT+0800 (CST),
- updated_at: Tue Nov 03 2015 15:25:27 GMT+0800 (CST),
- user_id: 1 } }
- */</span></span></span></span></span></span></span></span></code>
SQL
:
- <code class="sql"><span class="hljs-keyword">SELECT <span class="hljs-string">`user`.<span class="hljs-string">`id`, <span class="hljs-string">`user`.<span class="hljs-string">`emp_id`, <span class="hljs-string">`user`.<span class="hljs-string">`created_at`, <span class="hljs-string">`user`.<span class="hljs-string">`updated_at`, <span cl="" <="" div="">
- <div class="">
- <ul class="m-news-opt fix">
- <li class="opt-item">
- <a href="/sql_question-428617.html" target="_blank"><p>< 上一篇</p><p class="ellipsis">处理本地数据库和云数据库存储的注意事项</p></a>
- </li>
- <li class="opt-item ta-r">
- <a href="/sql_question-428619.html" target="_blank"><p>下一篇 ></p><p class="ellipsis">db2导出数据并导入hive临时表中</p></a>
- </li>
- </ul>
- </div>
- </span></span></span></span></span></span></span></span></span></span></code>
人气教程排行
-
229次
1
oracle 用户解锁和修改用户密码
-
229次
2
解决:安装SQL Server 2008 Native Client遇到错误(在Navicat premium新建sqlserver连接时 需要):An error occurred during ...HRESULT: 0x80070422(注意尾部的错误号)
-
229次
3
rocksdb 编译步骤
-
229次
4
adb命令开关蓝牙及NFC
-
229次
5
解决数据库连接错误 您在wp-config.php文件中提供的数据库用户名和密码可能不正确,或者无法连接到localhost上的数据库服务器,这意味着您的主机数据库服务器已停止工作。
-
229次
6
使用java自动填充,实现mysql的创建修改时间的自动填充
-
229次
7
Linux mount挂载磁盘报错 mount: wrong fs type, bad option, bad superblock on /dev/vdb
-
228次
8
关于mysql创建数据库中字符集和排序规则的选择
-
228次
9
Linux设置Mysql开机自启动服务
-
227次
10
SQL2008:WITH MOVE 子句可用于重新定位一个或多个文件
-
227次
11
图数据库Neo4j在GIS系统的应用
-
227次
12
SpringBoot配置 druid 数据源配置 慢SQL记录
-
227次
13
SQL state [72000]; error code [1013]; ORA-03111: 通信通道收到中断; java.sql.SQLException: ORA-01745: 无效的主机/绑定变量名;java.sql.SQLException: ORA-01013: 用户请求取消当前的操作
-
227次
14
docker-compose启动MySQL并配置远程登录
-
225次
15
Mysql安装(for mac)
-
225次
16
kettle将图片转换至二进制存储至数据库
-
225次
17
adb的安装及配置
-
224次
18
使用PHP控制MODBUS-RTU设备
-
224次
19
MySQL 查询时间差值大于某一个值的 记录
-
224次
20
MongoDB内存配置 --wiredTigerCacheSizeGB