利用 Sequelize 来操作数据库

利用传说中的ORM技术,把关系数据库的表结构映射到对象上,简化数据库操作。

Published: 2019-3-01

Sequelize 是一个基于 Prom 的 ORM for Node,面向熟悉 JavaScript 和使用 Node.js 进行后端开发的开发人员。在本篇文章中,将探讨 Sequelize 的一些常见用例以及 利用 Sequelize-cli 完成相关的环境配置。

  1. Sequelize 极简入门教程;
  2. Sequelize-cli 完成 dev,test,prod 环境的配置,以及数据库创建;
  3. Sequelize-cli 完成表结构的设计、迁移与数据填充;
  4. Sequelize 结合 Sequelize-cli 完成数据库的增、删、改、查;
  5. 总结。

Sequelize 极简入门教程

本章代码,here

ORM:Object-Relational Mapping,就是允许将关系数据库映射到对象上,使得这些对象具有一些属性和操作数据库的方法,避免编写 SQL 语句。

Sequelize:Sequelize 是一款基于 Nodejs 功能强大的异步ORM框架,同时支持 PostgreSQL,MySQL,SQLite 等多种数据库,很适合作为Nodejs后端数据库的存储接口。

本节简单利用 Sequelize 向数据库中插入一条数据,方便后续理解 Sequelize-cli。

安装

可以利用 npmyarn 完成安装

// Using NPM
$ npm install --save sequelize

# And one of the following:
$ npm install --save pg pg-hstore
$ npm install --save mysql2
$ npm install --save sqlite3
$ npm install --save tedious // MSSQL

// Using Yarn
$ yarn add sequelize

# And one of the following:
$ yarn add pg pg-hstore
$ yarn add mysql2
$ yarn add sqlite3
$ yarn add tedious // MSSQL
复制代码

本文依赖 mysql,所以

$ npm install --save sequelize
$ npm install --save mysql2
复制代码
建立与数据库连接

Sequelize 提供了两种连接数据库的方式

const Sequelize = require('sequelize');
// 数据库相关参数
const sequelize = new Sequelize('database', 'username', 'password', {
    // 所在ip
    host: 'localhost',
    // 所用端口
    port: '端口',
    // 所用数据库类型
    dialect: 'mysql'|'sqlite'|'postgres'|'mssql',
    // 请参考 Querying - 查询 操作符 章节
    operatorsAliases: false,
    // 设置连接池,因此如果您从单个进程连接到数据库,理想情况下应该只为每个数据库创建一个实例
    pool: {
        max: 5,
        min: 0,
    	acquire: 30000,
    	idle: 10000
  	},
    // 执行过程会log一些SQL的logging,设为false不显示
  	logging: false,

  	// SQLite only
  	storage: 'path/to/database.sqlite'
});

// 利用 uri 简易连接数据库
const sequelize = new Sequelize('postgres://user:pass@example.com:5432/dbname');
复制代码

本文所用数据库为 mysql,结合 sequelize.authenticate 来对连接进行测试,构建 index.js

const Sequelize = require('sequelize');

const sequelize = new Sequelize('users_dev', 'username', 'password', {
    host: 'localhost',
    port: 3306,
    dialect: 'mysql',
    operatorsAliases: false,
    // logging: false,

    pool: {
        max: 5,
        min: 0,
        acquire: 30000,
        idle: 10000
    },
});

sequelize
    .authenticate()
    .then(() => {
        console.log('Connection has been established successfully.');
        process.exit();
    })
    .catch(err => {
        console.error('Unable to connect to the database:', err);
    });
复制代码

利用 node index.js 运行该脚本,成功的会打印出 Connection has been established successfully.

定义 Model,并插入数据

Model 主要是用来完成与表之间的映射,主要利用 sequelize.define('name', {attributes}, {options}) 完成 Model 的定义。我们定义一个 User 模型对应 user 表。

const User = sequelize.define('user', {
    // 即使表的结构也是Model的属性
    firstName: {
        type: Sequelize.STRING
    },
    lastName: {
        type: Sequelize.STRING
    }
});
复制代码

利用已经定义好的Model,可以完成对 user 表的插入数据操作

// force: true will drop the table if it already exists
User.sync({
    force: true
}).then(() => {
    // Table created
    return User.create({
        firstName: 'John',
        lastName: 'Hancock'
    });
}).then(() => {
    process.exit()
})
复制代码

以上完成 Sequelize 的极简介绍,主要想介绍一个映射的流向,方便后续理解,官网实例更加详细

Sequelize-cli 完成 dev,test,prod 环境的配置,以及数据库创建

本章代码,here

与 Sequelize 相伴的有 Sequelize-cli 工具,Sequelize-cli 为我们提供了一系列好用的终端指令,来完成以下工作

  • 配置不同的环境的数据库连接,例如dev、test、prod等;
  • 自动管理表对应的 Model;
  • 利用 migrations 完成数据库的表结构的迁移;
  • 利用 seeders 完成数据库的表内容的初始化。

首先安装 Sequelize-cli

npm i sequelize-cli -D
复制代码

在 package.json 中添加

"scripts": {
    "init": "node_modules/.bin/sequelize init",
    ...
}
复制代码

运行 npm run init 命令,之后会发现,在目录下多了 config、models、migrations、seeders四个文件夹

├── config # 项目配置目录 | ├── config.json # 数据库连接的配置 ├── models # 数据库 model | ├── index.js # 数据库连接的样板代码 ├── migrations # 数据迁移的目录 ├── seeders # 数据填充的目录

本节只考虑配置相关的,也就是config文件夹下的内容,主要包含 config.json

{
    "development": {
        "username": "root",
        "password": null,
        "database": "database_development",
        "host": "127.0.0.1",
        "dialect": "mysql"
    },
    "test": {
        "username": "root",
        "password": null,
        "database": "database_test",
        "host": "127.0.0.1",
        "dialect": "mysql"
    },
    "production": {
        "username": "root",
        "password": null,
        "database": "database_production",
        "host": "127.0.0.1",
        "dialect": "mysql"
    }
}
复制代码

主要包含了 development、test、production,三个环境下的数据库信息。

之前我也是利用 config.json 来管理的,但是之后通过阅读基于 hapi 的 Node.js 小程序后端开发实践指南,发现利用 .env 文件来管理是一种更为优雅的方法。

安装 env2 插件,在当前目录下创建 .env 文件用于配置开发环境以及生产环境的基础信息。

npm i -D env2
复制代码

.env 内容,注字符串变量不需要''。

DB_USERNAME = username
DB_PASSWORD = password
DB_NAME = dataname
DB_NAME_PROD = prodDataname
DB_HOST = *.*.*.*
DB_PORT = *
复制代码

如果 git 非私密的,需要配置 .gitignore 的相关信息,在config文件下,创建config.js

require('env2')('./.env');

const {
    env
} = process;

module.exports = {
    "development": {
        "username": env.DB_USERNAME,
        "password": env.DB_PASSWORD,
        "database": env.DB_NAME,
        "host": env.DB_HOST,
        "port": env.DB_PORT,
        "dialect": "mysql",
        "operatorsAliases": false,
    },
    "production": {
        "username": env.DB_USERNAME,
        "password": env.DB_PASSWORD,
        "database": env.DB_NAME_PROD,
        "host": env.DB_HOST,
        "port": env.DB_PORT,
        "dialect": "mysql",
        "operatorsAliases": false,
    }
}
复制代码

同时修改models文件夹下的index.js

// .json => .js
const config = require(__dirname + '/../config/config.js')[env];
复制代码

以上利用env2完成对开发环境,生产环境的config配置,添加 create 以及 create:prod 两条指令

"scripts": {
    "init": "node_modules/.bin/sequelize init",
    "create": "node_modules/.bin/sequelize db:create",
    "create:prod": "node_modules/.bin/sequelize db:create --env production",
    ...
}
复制代码

可创建开发环境、生产环境的的数据库。

Sequelize-cli 完成表结构的设计、迁移与数据填充

本章代码,here

表结构的设计、迁移都与 Migrations 相关

就像使用Git / SVN管理源代码中的更改一样,可以使用 Migration 来初始化数据库、或跟踪数据库更改,也就是说通过配置 Migration 文件可以将现有数据库迁移至另一个状态,并且保存记录。

"scripts": {
	...
	"migration": "node_modules/.bin/sequelize migration:create --name create-examples-table",
	"migration:prod": "node_modules/.bin/sequelize migration:create --name create-examples-table --env production"
	...
}
复制代码

首先在开发环境下进行测试,执行 npm run migration 指令,之后会在 migrations 文件夹内创建一个20190301054713-create-examples-table.js 文件,内容为

'use strict';

module.exports = {
  up: (queryInterface, DataTypes) => {
    /*
      Example:
      return queryInterface.createTable('users', { id: DataTypes.INTEGER });
    */
  },

  down: (queryInterface, DataTypes) => {
    /*
      Example:
      return queryInterface.dropTable('users');
    */
  }
};
复制代码

模块暴漏出一个对象,包含着 updown 两个方法,up 用于定义表结构正向改变,down 则用于定义表结构的回退,对应其中的 return ,正向 createTable ,反向则是 dropTable

两个参数的定义:

  • queryInterface:用于定义Sequelize与所属数据库通信的接口,包含一些API,例如createTable用于创建表,dropTable则用于撤销,addColumn用于追加字段,removeColumn则用于移除;

  • DataTypes:用于定义接口数据的类型。

queryInterface.createTable(...) 整体功能与 sequelize.define(...) 类似。简单设计如下表

'use strict';

module.exports = {
    up: (queryInterface, DataTypes) => {
        return queryInterface.createTable('users', {
            id: {
                type: DataTypes.INTEGER,
                autoIncrement: true,
                primaryKey: true,
            },
            name: {
                type: DataTypes.STRING,
                allowNull: false,
            },
            created_at: DataTypes.DATE,
            updated_at: DataTypes.DATE,
        });
    },

    down: (queryInterface) => {
        return queryInterface.dropTable('users');
    }
};
复制代码

添加如下指令

"scripts": {
	...
	"migrate": "node_modules/.bin/sequelize db:migrate",
    "migrate:prod": "node_modules/.bin/sequelize db:migrate --env production",
	...
}
复制代码

运行 npm run migrate ,会将 migrations 目录下的迁移行为定义,按时间戳的顺序,逐个地执行迁移描述,最终完成数据库表结构的自动化创建。会发现数据库examples_dev内创建了一张 SequelizeMeta 的表以及 users 的表:

  • SequelizeMeta:记录了对应迁移文件的信息;
  • users:是利用 queryInterface.createTable 创建的表。

相应的也有 node_modules/.bin/sequelize db:migrate:undo 来撤销相应的迁移,这里就不展开介绍了。

数据填充

主要利用 seeders 来在初始化数据表中中初始化一些基础数据,使用方式与数据库表结构迁移相似,添加如下指令。

"scripts": {
	...
	"seeder": "node_modules/.bin/sequelize seed:create --name init-users",
    "seeder:prod": "node_modules/.bin/sequelize seed:create --name init-users --env production",
	...
}
复制代码

运行 npm run seed 指令,则与数据迁移相同的是,seeders 文件夹下多了一个 ***init-users.js 文件,结构也和数据迁移类似。

'use strict';

module.exports = {
    up: (queryInterface, Sequelize) => {
        /*
          Example:
          return queryInterface.bulkInsert('People', [{
            name: 'John Doe',
            isBetaMember: false
          }], {});
        */
    },

    down: (queryInterface, Sequelize) => {
        /*
          Example:
          return queryInterface.bulkDelete('People', null, {});
        */
    }
};
复制代码

参数也相同,只不过一个是创建表,一个是创建数据,所利用的API不同而已,例如。

'use strict';

module.exports = {
    up: (queryInterface, Sequelize) => {
        return queryInterface.bulkInsert('users', [{
            name: 'John Doe',
            created_at: new Date(),
            updated_at: new Date()
        }], {});
    },

    down: (queryInterface, Sequelize) => {
        return queryInterface.bulkDelete('users', null, {});
    }
};
复制代码

添加指令

"scripts": {
    ...
    "seed": "node_modules/.bin/sequelize db:seed:all",
    "seed:prod": "node_modules/.bin/sequelize db:seed:all --env production",
    ...
}
复制代码

也可以用 node_modules/.bin/sequelize db:seed --seed xxxxxxxxx-init-users.js 来指定添充数据。

Sequelize 结合 Sequelize-cli 完成数据库的增、删、改、查

本章代码,here

在第一节中,简单介绍了 User.create(...) 插入了一条数据,本节中介绍结合 Sequelize-cli 完成对数据库的增、删、改、查。

在 Models 文件夹下创建对应的模型文件 users.js,内容与第一节 sequelize.define(...) 类似

module.exports = (sequelize, DataTypes) => sequelize.define(
    'users', {
        id: {
            type: DataTypes.INTEGER,
            autoIncrement: true,
            primaryKey: true,
        },
        name: {
            type: DataTypes.STRING,
            allowNull: false,
        }
    }, {
        tableName: 'users',
        // 以下两个属性是针对createAt、updateAt这两个默认属性的,timestamps是不使用,而underscored
        // 则是将createAt转化为create_at
        // timestamps: false,
        underscored: true,
    }
)
复制代码

模型结构,与数据迁移相同,在 index.js 文件内引入模型

const { users } = require("./models");
复制代码

可以利用该 Model 完成对表 users 的操作,主要以下几个

  • 查:findAllfindByPkfindCreateFindfindOrCreate.....

    const { users } = require("./models");
    
    (async () => {
        // 搜索多个实例
        const user = await users.findAll()
    	// 条件搜索name = 'John Doe'
        // const user = await users.findByPk(1)
    
        console.log(user)
    
        process.exit();
    })()
    复制代码
  • 增:createbulkCreate....

    const { users } = require("./models");
    
    (async () => {
        await users.create({
            name: 'Yang'
        })
    
        process.exit();
    })()
    复制代码
  • 删:destroydrop删表.....

    const { users } = require("./models");
    
    (async () => {
        await users.destroy({
            where: {
                name: 'Yang'
            }
        })
    
        process.exit();
    })()
    复制代码
  • 改:upsertupdate.....

    const { users } = require("./models");
    
    (async () => {
        await users.update({
            name: 'Yange'
        }, {
            where: {
                name: 'John Doe'
            }
        })
    /*    
        await users.upsert({
            name: 'Sccc'
        }, {
            where: {
                name: 'Yange'
            }
        })
    */
        process.exit();
    })()
    复制代码

总结


这篇主要是用来总结之前一直看到的零散知识,也是用来配置存底,防止自己忘了。之前用的 mongoose 到 Sequelize,感觉自己一直在切换工具,却又没有很好地入门了解。之后应该是会选择一个点深入了解下吧,对自己很是失望。

参考

http://docs.sequelizejs.com/class/lib/model.js~Model.html#static-method-upsert

https://juejin.im/book/5b63fdba6fb9a04fde5ae6d0/section/5b6c048e6fb9a04fdc36afc1

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 如果要使用 H5 写一个响应式页面,可以使用 Bootstrap、 Foundation 等 CSS 框架来实现。这些框架都提供了一系列的 CSS 类,可以让页面在不同尺寸的设备上得到优秀的展示效果。 如果要使用 Node.js 操作数据库,可以使用一些数据库驱动,如 MySQL、 MongoDB、Redis等。这些驱动都提供了一些 API,可以在 Node.js 中方便地操作数据库。 ### 回答2: 响应式页面是一种能够自动适应不同设备和屏幕尺寸的网页设计技术。使用H5(HTML5)语言可以轻松实现响应式页面。以下是一个简单的示例: 首先,我们需要在HTML文件的`<head>`标签中引入一个 H5 的 `<meta>` 标签,指定viewport 的宽度和初始缩放比例,从而使页面能根据设备自动适应。 接下来,在页面的结构中,我们使用CSS媒体查询(media query)来定义不同尺寸的布局和样式。例如,我们可以创建三个不同的CSS样式表:`mobile.css`、`tablet.css` 和 `desktop.css`,分别对应移动端、平板和桌面设备的布局样式。然后在 HTML 文件中,使用`<link>`标签将不同的样式表与媒体查询关联起来。 通过媒体查询,我们可以使用CSS的`@media`规则,在不同的屏幕尺寸下应用相应的样式和布局。例如,使用`@media screen and (max-width: 480px)`表示在视口宽度不超过480px时应用的样式。 在H5的语法和标签上,一般与之前的HTML4相比较少的,但可以使用一些新的元素和属性来增强用户体验,如`<canvas>`用于绘制图形、`<video>`用于播放视频等。另外,H5还增加了一些新的JavaScript API,如地理位置、离线存储等,通过这些API能够实现更丰富的功能和交互效果。 至于Node.js操作数据库,可以使用Node.js提供的模块来轻松实现。首先,我们需要使用npm(Node包管理器)来安装适当的数据库驱动程序,如`mysql`、`mongodb`等。 安装完驱动程序后,我们可以使用`require`函数在Node.js应用程序中引入相应的驱动程序。然后,创建数据库连接,并执行相关的数据库操作,如查询、插入、更新和删除等。具体的操作语法和方法根据所选的数据库驱动程序而异。 在操作数据库过程中,我们通常会使用回调函数或Promise来处理异步操作。通过回调函数,可以在数据库结果返回后执行特定的动作。而Promise则提供了一种更简洁和可读性更高的方式来处理异步操作。可以使用async/await语法糖来进一步简化异步操作的处理流程。 总而言之,通过合理利用H5和Node.js提供的各种功能和模块,我们可以轻松实现响应式页面设计和数据库操作。 ### 回答3: 用H5写一个响应式页面可以通过以下步骤完成: 1. 结构布局:使用HTML5语义化标签进行页面结构布局,如<header>、<nav>、<main>、<footer>等。通过媒体查询设置不同分辨率下的样式,并使用Flexbox或Grid来实现页面的自适应布局。 2. 图片和多媒体:使用<img>标签来插入图片,并使用CSS属性设置图片的宽度和高度,以适应不同设备的屏幕尺寸。为了提高页面加载速度,可以使用响应式图片技术,根据设备屏幕尺寸提供不同大小和分辨率的图片。 3. 文本内容:使用<p>、<h1>到<h6>等标签来进行文本内容的标记。使用CSS控制字体大小,行间距和对齐方式以适应不同屏幕。 4. 响应式导航:使用CSS实现响应式导航菜单,可以采用弹出式菜单、折叠式菜单或者水平菜单,根据屏幕尺寸进行切换。 5. 表单:使用<input>、<select>等标签创建表单,并使用CSS设置不同设备上的表单样式,确保用户输入的可见性和易用性。 Node.js操作数据库可以通过以下步骤完成: 1. 安装依赖:使用npm或yarn安装适当的Node.js模块,如mysql、mongodb或sequelize,这些模块帮助连接和操作不同类型的数据库。 2. 连接数据库:使用数据库模块提供的API,通过提供数据库主机、用户名、密码和数据库名等信息来建立与数据库的连接。 3. 执行数据库操作:使用数据库模块提供的API,执行查询、插入、更新或删除等操作。例如,通过调用适当的函数来执行SQL语句,或者使用ORM框架(如sequelize)提供的方法来操作数据库。 4. 处理结果:根据数据库操作的返回结果,进行适当的错误处理和数据处理。例如,可以通过回调函数或Promise来处理异步操作的结果,使用条件语句来处理错误情况,并将查询结果展示给用户。 5. 断开连接:当数据库操作结束后,使用数据库模块提供的API断开与数据库的连接,释放资源并保持数据库的安全性。 以上是使用H5写一个响应式页面和Node.js操作数据库的基本步骤,具体实现取决于项目需求和所使用的具体技术。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值