# db-use **Repository Path**: Lxinz/db-use ## Basic Information - **Project Name**: db-use - **Description**: nodejs+sequelize的数据库操作案例(迁移、表模型的增删改查) - **Primary Language**: Unknown - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2025-04-21 - **Last Updated**: 2025-04-21 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # sequelize数据库实操 技术栈:nodejs(type: module) + sequelize + mysql + dotenv-cli ## Sequelize 基础准备 > 默认你已经完成docker部署mysql,并创建了db_use的数据库,设置了数据库账号root/123456。 1、如果没有安装sequelize、sequelize-cli、相关数据库(比如mysql2),需要先安装 `npm install sequelize sequelize-cli mysql2` 2、在对应目录下,初始化 Sequelize(生成配置、迁移、种子目录等) `npx sequelize-cli init` **目录结构:** ```javascript project/ ├── config/ │ ├── .env.development // 开发环境配置 │ └── .env.production // 生产环境配置 ├── db/ │ ├── config/ │ │ └── config.js // 数据库配置文件 │ ├── models/ │ │ └── index.js │ ├── migrations/ │ │ └── [timestamp]-create-users-table.js │ └── seeders/ ├── .sequelizerc ├── package.json └── ... ``` 3、数据库配置(用于迁移) ```javascript // config/config.js export default { development: { username: process.env.DEV_DB_USERNAME, password: process.env.DEV_DB_PASSWORD, database: process.env.DEV_DB_DATABASE, host: process.env.DEV_DB_HOST, port: process.env.DEV_DB_PORT, dialect: process.env.DEV_DB_DIALECT, }, production: { username: process.env.PROD_DB_USERNAME, password: process.env.PROD_DB_PASSWORD, database: process.env.PROD_DB_DATABASE, host: process.env.PROD_DB_HOST, port: process.env.PROD_DB_PORT, dialect: process.env.PROD_DB_DIALECT, } }; ``` > 上面使用了dotenv来读取环境变量,需要安装npm install dotenv。 这里使用了环境变量去配置数据库的信息,环境变量放置在根目录的config下(具体可查看目录结构)。 ```javascript # .env.development NODE_ENV=development DEV_DB_USERNAME=root DEV_DB_PASSWORD=123456 DEV_DB_DATABASE=db_use DEV_DB_HOST=localhost DEV_DB_PORT=3306 DEV_DB_DIALECT=mysql # .env.production NODE_ENV=production PROD_DB_USERNAME=root PROD_DB_PASSWORD=123456 PROD_DB_DATABASE=db_use PROD_DB_HOST=localhost PROD_DB_PORT=3306 PROD_DB_DIALECT=mysql ``` 上面环境变量通过dotenv-cli,在scripts脚本配置时,直接指向了对于目录的环境配置,因此可以在项目中直接使用process.env.NODE_ENV这样的方式调用环境变量。 ```javascript // package.json的scripts区域中使用dotenv-cli参考 "scripts": { "serve": "dotenv -e config/.env.development node index.js", "serve:prod": "dotenv -e config/.env.production node index.js", "migrate:up": "dotenv -e config/.env.development npx sequelize-cli db:migrate --env=development", "migrate:undo": "dotenv -e config/.env.development npx sequelize-cli db:migrate:undo --env=development", "migrate:up:prod": "dotenv -e config/.env.production npx sequelize-cli db:migrate --env=production", "migrate:undo:prod": "dotenv -e config/.env.production npx sequelize-cli db:migrate:undo --env=production" }, ``` ## Sequelize 表迁移步骤(生产推荐使用) 1、新建一个迁移文件 `npx sequelize-cli migration:generate --name create-users-table` 2、手动修改迁移文件内容(修改为ES语法、添加数据库字段) ```javascript export default { up: async (queryInterface, Sequelize) => { await queryInterface.createTable('Users', { id: { allowNull: false, autoIncrement: true, primaryKey: true, type: Sequelize.INTEGER, }, name: { type: Sequelize.STRING, }, email: { type: Sequelize.STRING, unique: true, }, createdAt: { allowNull: false, type: Sequelize.DATE, }, updatedAt: { allowNull: false, type: Sequelize.DATE, }, }); }, down: async (queryInterface, Sequelize) => { await queryInterface.dropTable('Users'); }, }; ``` > await queryInterface.dropTable('Users')作用? > 用于 **回滚迁移的操作(undo migration)**,当执行npx sequelize-cli db:migrate会运行 `up()` 方法,创建 `Users` 表;当执行npx sequelize-cli db:migrate:undo会运行 `down()` 方法,这时候 `dropTable('Users')` 就会生效,把 `Users` 表删掉。 > > 需要注意的是,个迁移文件的话,`db:migrate:undo` 只会回滚最后一个迁移文件。如果你想一次性回滚所有迁移,则执行npx sequelize-cli db:migrate:undo:all即可。 2、项目根目录配置.sequelizerc 这样可以在项目的根目录去执行迁移指令,或者封装到package.json的scripts中也可以正常使用了。 ```javascript // .sequelizerc 文件 // 注意:sequelizerc的配置文件一定要使用commonjs规范,不能使用es6规范,否则使用sequelize-cli会无法识别配置信息 const path = require('path'); module.exports = { 'config': path.resolve('db', 'config', 'config.js'), 'models-path': path.resolve('db', 'models'), 'seeders-path': path.resolve('db', 'seeders'), 'migrations-path': path.resolve('db', 'migrations'), }; ``` 3、执行迁移 在项目根目录下执行: `npx sequelize-cli db:migrate --env=development` 其中的 `development` 参数指的是你在 `sequelize` 初始化的 `config/config.js` 文件中配置的某一个环境;如果你不加 `--env` 参数,Sequelize CLI 默认使用 `development` 环境。 ## Sequelize 数据迁移-种子操作(Seed) 1、创建种子文件 `npx sequelize-cli seed:generate --name update-user` 2、编辑种子文件 ```javascript export default { async up (queryInterface, Sequelize) { /** * Add seed commands here. * * Example: * await queryInterface.bulkInsert('People', [{ * name: 'John Doe', * isBetaMember: false * }], {}); */ await queryInterface.bulkInsert('Users', [{ name: 'John Doe', email: '12345678910@qq.com', createdAt: new Date(), updatedAt: new Date() }], {}); }, async down (queryInterface, Sequelize) { /** * Add commands to revert seed here. * * Example: * await queryInterface.bulkDelete('People', null, {}); */ await queryInterface.bulkDelete('Users', null, {}); } }; ``` 如果只更新表中指定的某条数据的部分字段,可以在up函数中的queryInterface.bulkInsert方法的第二个参数传入一个对象,第三个参数传入查询参数。 ```javascript await queryInterface.bulkUpdate( 'Users', { name: '李四' }, // 更新内容 { id: 1 } // where 条件 ); ``` 3、执行种子插入 `npx sequelize-cli db:seed:all --env=development` ## 增删改查实操 1、在db/models下创建对应数据库的表模型,比如User.js,内容可以参考迁移文件中对应的表进行编写。 ```javascript export default (sequelize, DataTypes) => { const Users = sequelize.define('Users', { id: { type: DataTypes.INTEGER, autoIncrement: true, primaryKey: true, }, name: { type: DataTypes.STRING, }, email: { type: DataTypes.STRING, unique: true, }, }, { // 启动时间,设置为ture会自动生成创建和更新时间,默认字段名称为createAt、updateAt。 timestamps: true, // 对应的表名将与model名相同 freezeTableName: true, // 表备注 comment: '用户表', }); return Users; }; ``` > 需要注意的是,如果迁移表中创建了createdAt、updatedAt等时间自动,可以在表模型文件中通过配置属性timestamps去实现自动创建和更新,也就不需要在表模型的字段定义中再次定义了。 > > 如果是先写了表模型文件,想编写对应的迁移文件,就需要注意,如果有timestamps字段定义的,需要在迁移文件中自行创建。 之后,会在db/models/index.js中自动引入,并导出sequelize实例和表模型的一个对象db,通过db就可以进行数据库对应表的增删改查了。 2、比如以上面创建的Users表为例,在项目的根目录的入口index.js中实现增删改查。 ```javascript // index.js import db from './db/models/index.js'; const { Users } = db; // 增加 const newUser = await Users.create({ name: 'Tom', email: 'tom@example.com' }); // 查询 const User = await Users.findOne({ where: { email: 'tom@example.com' } }); console.log(User.toJSON()); // 更新 await Users.update({ name: 'Tommy' }, { where: { email: 'tom@example.com' } }); // 删除 await Users.destroy({ where: { email: 'tom@example.com' } }); ```