koa2开发后台服务 - (3) sequelize - 数据建模以及数据同步

nodejs操作mySql数据库 中已经介绍了怎么使用nodejs链接mysql数据库,以及t通过Promise的方式封装了mysql执行sql获取数据,以及防止sql注入的escape方法。本章介绍orm数据关系映射 - Sequelize.

ORM

  • Object Relation Mapping

数据表,用js中的模型(class或者对象)代替

一条或多条记录,用对象或者数组代替

sql语句,使用对象的方法代替

(1) 安装mysql和sequelize

npm i mysql2 sequelize –save

(2) 配置sequelize建立数据库连接

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
const Sequelize = require('sequelize')

// 引入mysql配置
const { mysqlConfig: { database, username, password, host,dialect,pool } } = require('../conf/db')

/*
* @params {string} - database 数据库名称
* @params {string} - username 用户名
* @params {string} - password 密码
* @params {Object} - host主机地址,dialect数据库类型,pool连接池
*/
const seq = new Sequelize(database, username, password, {
host,
dialect,
pool // 线上环境需要使用连接池
})

module.exports = seq // 导出sequelize连接实例

(3)sequelize建模&同步到数据库

  • 之前nodejs直接连接mysql,需要在mysql中先建表,然后再nodejs中通过mysql的connect实例进行sql的查询。

  • sequelize通过数据建模,然后就会同步到数据库中生成响应的表,然后通过api的方式进行增删改查,以及多表查询等操作。

sequelize是通过define方法建立模型的,Model相当于数据库中的表,该对象不能通过构造函数实例化,而只能通过sequelize.define()sequelize.import()方法创建

(3-1)创建数据模型

sequelize.define():define方法接收三个参数,第一个参数为表名称,第二个为所需要创建的数据库字段,第三个参数是相关表配置,具体配置参考文章结尾的连接 详细配置

更多阅读配置参数

Sequelize常用的数据类型,文章结尾有详细的列表

  • Sequelize.NOW - 获取当前时间
  • Sequelize.STRING
  • Sequelize.INTEGER
  • Sequelize.TEXT
  • Sequelize.DATE
  • Sequelize.DECIMAL

数据模型中的参数

  • type - Sequelize提供的类型
  • allowNull - true/false 是否为空
  • comment 备注信息
  • pattern 按照正则匹配
  • defaultValue 默认值
  • unique - true/false是否唯一
  • primaryKey - true/false 定义主键
  • autoIncrement - true/false 可用于创建自增的整数列
  • field - 属性指定自定义字段名称
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
   const Sequelize = require('sequelize')
const seq = require('../seq') // 上面导出的sequelize连接实例

// 跟建立User表一样,define的第一个参数就是表名,后面是表的列和属性
const User = req.define('user',{
// id 会自动创建,并设置为主键,自增
username:{
type:Sequelize.STRING,
allowNull:false
},
password:{
type:Sequelize.STRING,
allowNull:false
},
nickname:{
type:Sequelize.STRING
}
})

module.exports = {
User
}

(3-2)创建数据表的外键

ModalA 多对一 ModalB

1
2
3
ModalA.belongsTo(ModalB,{
foreignKey:'ModalAForeignKeyName'
})

ModalB 一对多 ModalA

1
2
3
ModalB.hasMany(ModalA,{
foreignKey:'ModalAForeignKeyName'
})

  • 上面两种api二选一就行了,但是为了连表查询,所以都写比较好,查询ModalA带出来ModalB。必须写第一种写法。反之亦然。

(3-3)测试sequelize是否连接成功 - authenticate()方法

1
2
3
4
5
6
7
8
const seq = require('./seq') // 先导入sequelize连接实例
// 测试sequelize链接是否成功
seq.authenticate().then(() => {
console.log('sequelize connect successfully')
}).catch(err => {
console.log(err)
console.log('sequelize connect failed')
})

(3-4)同步模型到数据库 - sync()方法

force: true 如果表已经存在,将会丢弃表 ;

alter: true 如果表已存在,不丢弃,如果不存在会直接创建表

需要注意通过这种方式同步的表会在表名称后面添加一个s作为复数

会自动生成createdAt的创建时间,和修改时间updateAt,如果不需要这两个参数的话在define的第三个参数中修改表配置timestamps为false,默认为true

1
2
3
4
5
6
7
8
9
const AaronTest = sequelize.define('project', {
title: Sequelize.STRING,
description: {
type:Sequelize.txt,
allowNull:false
}
},{
timestamps: false // 不要添加时间戳属性 (updatedAt, createdAt)
})

force的意思是同步中存在的表会删掉,重新创建一个新的

同步成功需要手动退出进程process.exit()

会自动生成id,并且设置成主键,自动增加

1
2
3
4
5
6
7
8
9
10
11
const seq = require('./seq') // 先导入sequelize连接实例

require('/modal); // 导入创建的模型
// 执行同步
seq.sync({force:true}).then(() => {
process.exit(); // 同步成功需要手动退出进程
console.log('sequelize sync successfully')
}).catch(err => {
console.log(err)
console.log('sequelize sync failed')
})

同步数据

在workbench中就可以看到数据表已经同步过来了。在Database=>Reverse Engineer 就可以生成E-R实体关系图
实体关系图

补充文档 - 详细的模型参数和类型参数

Model definition - 模型定义如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
const Foo = sequelize.define('foo', {
// 如果未赋值,则自动设置值为 TRUE
flag: { type: Sequelize.BOOLEAN, allowNull: false, defaultValue: true},

// 设置默认时间为当前时间
myDate: { type: Sequelize.DATE, defaultValue: Sequelize.NOW },

// 将allowNull设置为false会将NOT NULL添加到列中,
// 这意味着当列为空时执行查询时将从DB抛出错误。
// 如果要在查询DB之前检查值不为空,请查看下面的验证部分。
title: { type: Sequelize.STRING, allowNull: false},

// 创建具有相同值的两个对象将抛出一个错误。 唯一属性可以是布尔值或字符串。
// 如果为多个列提供相同的字符串,则它们将形成复合唯一键。
uniqueOne: { type: Sequelize.STRING, unique: 'compositeIndex'},
uniqueTwo: { type: Sequelize.INTEGER, unique: 'compositeIndex'},

// unique属性用来创建一个唯一约束。
someUnique: {type: Sequelize.STRING, unique: true},
// 这与在模型选项中创建索引完全相同。
{someUnique: {type: Sequelize.STRING}},
{indexes: [{unique: true, fields: ['someUnique']}]},

// primaryKey用于定义主键。
identifier: { type: Sequelize.STRING, primaryKey: true},

// autoIncrement可用于创建自增的整数列
incrementMe: { type: Sequelize.INTEGER, autoIncrement: true },

// 你可以通过'field'属性指定自定义字段名称:
fieldWithUnderscores: { type: Sequelize.STRING, field: 'field_with_underscores' },

// 这可以创建一个外键:
bar_id: {
type: Sequelize.INTEGER,

references: {
// 这是引用另一个模型
model: Bar,

// 这是引用模型的列名称
key: 'id',

// 这声明什么时候检查外键约束。 仅限PostgreSQL。
deferrable: Sequelize.Deferrable.INITIALLY_IMMEDIATE
}
}
})

sequelize提供的几种数据类型,用于数据建模

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
Sequelize.STRING                      // VARCHAR(255)                  类型:字符串 最大值: 65535个字符
Sequelize.STRING(1234) // VARCHAR(1234) 类型:变长 最大值: 65535个字符
Sequelize.TEXT // TEXT 类型:字符串 最大值:65535个字符
Sequelize.TEXT('tiny') // TINYTEXT 类型:字符串 最大值:255个字符

Sequelize.INTEGER // INTEGER 类型:整型 最大值:范围(-2147483648~2147483647)
Sequelize.BIGINT // BIGINT 类型:整型 最大值:范围(+-9.22*10的18次方)
Sequelize.BIGINT(11) // BIGINT(11) 类型:整型 最大值:范围(+-9.22*10的18次方)

Sequelize.FLOAT // FLOAT 类型:单精度浮点型 8位精度(4字节)
Sequelize.FLOAT(11) // FLOAT(11) 类型:单精度浮点型 8位精度(4字节)
Sequelize.FLOAT(11, 12) // FLOAT(11,12) 类型:精度浮点型 8位精度(4字节) m总个数,d小数位


Sequelize.DOUBLE // DOUBLE 类型:双精度浮点型 16位精度(8字节)
Sequelize.DOUBLE(11) // DOUBLE(11) 类型:双精度浮点型 16位精度(8字节)
Sequelize.DOUBLE(11, 12) // DOUBLE(11,12) 类型:双精度浮点型 16位精度(8字节) m总个数,d小数位

Sequelize.DECIMAL // DECIMAL 类型:定点数型
Sequelize.DECIMAL(10, 2) // DECIMAL(10,2) 类型:定点数型 参数m<65 是总个数,d<30且 d<m 是小数位

Sequelize.DATE // DATETIME 类型:日期时间类型 范例:'2009-05-12 02:31:44'
Sequelize.DATE(6) // DATETIME(6)
Sequelize.DATEONLY // DATE without time.
Sequelize.BOOLEAN // TINYINT(1) 类型:整型 范围(-128~127)

Sequelize.ENUM('value 1', 'value 2') // ENUM 类型:枚举

Sequelize.BLOB // BLOB 类型:二进制数据
Sequelize.BLOB('tiny') // TINYBLOB 类型:二进制数据

参考连接

Sequelize 中文文档 v4 - Model definition - 模型定义

Sequelize 中 Model 的数据类型对应MySQL中的数据类型

Sequelize手记 - (一)

初到贵宝地,有钱的给个钱场,没钱的挤一挤给个钱场