node ORM (sequelize)使用、查询、验证及express 基础框架的搭建及实例的使用

一、安装sequelize-cli脚手架

npm  i  -g sequelize-cli
// 安装sequelize  mysql2
npm i sequelize mysql2
文件或目录说明
config/config.js数据库链接配置
migrations迁移文件 (创建修改表)
models模型文件
seeders种子文件

初始化

sequelize  init

修改config.json文件
在这里插入图片描述

development:本地环境
test:测试环境
production:线上环境
username: 数据库用户名
password:数据库密码
database:数据库名
dialect:这里可以改成任意一种关系型数据库
timezone: ‘+08:00’ 这里是东八区,默认为0时区
pool: { 使用连接池
max: 5,
min: 0,
acquire: 30000,
idle: 10000,
},

{
  "development": {
    "username": "root",
    "password": "xiewei",
    "database": "test",
    "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"
  }
}

通过sequelize-cil 实现创建表

文档sequelize-cil

步骤命令说明
第一步sequelize model:generate --name 模型名 --attributes 字段设置建模型和迁移文件
第二步人工处理根据需求调整迁移文件
第三步sequelize db:migrate运行迁移文件,生成数据表
第四步sequelize seed:generate --name 表名新建种子文件
第五步人工处理生成自己想要的文件
第六步sequelize db:seed --seed 种子文件名运行种子文件,将数据生成到数据库
其他sequelize migration:create --name 文件名在镜像中新增字段
1.命令行操作

sequelize model:generate:生成模型及其迁移
name: 模型名 建议大写必须单数 会在数据库生成articles
attributes:字段设置

sequelize model:generate --name Article --attributes title:string,content:text;
2.会自动在migrations目录下生成20241211080006-create-article当前时间下的js文件

在这里插入图片描述

3.运行迁移 使其可以在mysql数据库中增加表
sequelize db:migrate

在这里插入图片描述
多出来一个sequelizemeta表 用来记录已经跑过的哪些迁移防止重复迁移

4.插入数据

生成种子文件

sequelize seed:generate --name articie

创建100个数据

在这里插入图片描述

bulkInsert(“表名”, 数据, {配置参数});

"use strict";

/** @type {import('sequelize-cli').Migration} */
module.exports = {
  async up(queryInterface, Sequelize) {
    /**
     * Add seed commands here.
     *
     * Example:
     * await queryInterface.bulkInsert('People', [{
     *   name: 'John Doe',
     *   isBetaMember: false
     * }], {});
     */
    const articles = [];
    const counts = 100;
    for (let i = 1; i <= counts; i++) {
      const article = {
        title: `文章的标题 ${i}`,
        content: `文章的内容 ${i}`,
        createdAt: new Date(),
        updatedAt: new Date(),
      };
      articles.push(article);
    }
    await queryInterface.bulkInsert("articles", articles, {});
  },

  async down(queryInterface, Sequelize) {
    await queryInterface.bulkDelete("articles", null, {});

    /**
     * Add commands to revert seed here.
     *
     * Example:
     * await queryInterface.bulkDelete('People', null, {});
     */
  },
};

运行文件生成数据

xxx-article:种子文件名

sequelize db:seed --seed xxx-article

在这里插入图片描述

二、查询

1.在正确的路由页面引入模型

/router/article.js

const { Article } = require("../../models");

具体代码

const express = require("express");
const router = express.Router();
const { Op } = require("sequelize");
const { Article } = require("../../models");

// 必须用async await 才能获取到数据
router.get("/article", async function (req, res, next) {
  try {
    const query = req.query;
    
    // 分页查询

    // 当前是第几页,如果不传,默认第一页
    const currentPage = Math.abs(Number(query.currentPage)) || 1;

    // 每页显示多少条数据,如果不传,默认显示10条
    const pageSize = Math.abs(Number(query.pageSize)) || 10;
    // 从第几个索引开始查找
    const offset = (currentPage - 1) * pageSize;

    // 排序
    const condition = {
      order: [["id", "desc"]],
      limit: pageSize, // limit 显示数量
      offset, // 从第几个索引开始
    };

    // 模糊查询
    if (query.title) {
      condition.where = {
        title: {
         // LIKE 模糊查找 eq 精确查找
          [Op.like]: `%${query.title}%`,
        },
      };
    }

    // findAndCountAll异步操作
    const { count, rows } = await Article.findAndCountAll(condition);

    res.json({
      status: 200,
      message: "查询成功",
      data: {
        articles: rows,
        pagination: {
          total: count,
          currentPage,
          pageSize,
        },
      },
    });
  } catch (err) {
    res.json({ status: 1064, message: "查询失败", errors: [err.message] });
  }
});

sequelize操作

模糊查询(需在文章头部引入Op对象)
const { Op } = require(“sequelize”);

1.查全部数据
findAll()
2.差主键
findByPk(主键值)
3.插入语句
create(参数)
4.删除:找到要删除的数据 执行destroy()
const articles = await Article.findByPk(id);
await articles.destroy();
5.更新:找到要删除的数据 执行update(参数)
const articles = await Article.findByPk(id);
await articles.update(req.body);
6.负责语句查询: 直接用query + sql语法
  const [results] = await sequelize.query("SELECT DATE_FORMAT(`createdAt`, '%Y-%m') AS `month`, COUNT(*) AS `value` FROM `Users` GROUP BY `month` ORDER BY `month` ASC");

7.分页、排序、模糊查询
const query = req.query;

// 分页查询
// 当前是第几页,如果不传,默认第一页
const currentPage = Math.abs(Number(query.currentPage)) || 1;
// 每页显示多少条数据,如果不传,默认显示10条
const pageSize = Math.abs(Number(query.pageSize)) || 10;
// 从第几个索引开始查找
const offset = (currentPage - 1) * pageSize;

// 排序
const condition = {
  order: [["id", "desc"]],
  limit: pageSize, // limit 显示数量
  offset, // 从第几个索引开始
};

// 模糊查询
if (query.title) {
  condition.where = {
    title: {
      [Op.like]: `%${query.title}%`,
    },
  };
}

// findAndCountAll异步操作 count:总查询条数 rows 查询的结果
 const { count, rows } = await Article.findAndCountAll(condition);
 res.json({
   status: 200,
   message: "查询成功",
   data: {
     articles: rows,
     pagination: {
       total: count,
       currentPage,
       pageSize,
     },
   },
 });

3、增加验证/models/article.js 具体验证规则sequelize验证与约束

在这里插入图片描述

"use strict";
const { Model } = require("sequelize");
module.exports = (sequelize, DataTypes) => {
  class Article extends Model {
    /**
     * Helper method for defining associations.
     * This method is not a part of Sequelize lifecycle.
     * The `models/index` file will call this method automatically.
     */
    static associate(models) {
      // define association here
    }
  }
  Article.init(
    {
      title: {
        type: DataTypes.STRING,
        // allowNull 必须为false 才可以自定义验证
        allowNull: false,
        validate: {
          notNull: {
            mag: "标题必须存在",
          },
          notEmpty: {
            msg: "标题不能为空",
          },
          len: {
            args: [2, 45],
            msg: "标题长度需要在2-45个字符之间",
          },
          // 唯一校验
          async isUnique(value) {
            const titles = await Article.findOne({ where: { title: value } });
            if (titles ) {
              throw new Error("标题已存在");
            }
          },
        },
      },
      rank: {
        type: DataTypes.INTEGER,
        isInt: { msg: "排序必须为整数" },
        notEmpty: { msg: "必须不会空" },
        notNull: { msg: "必须存在" },
        // 自定义
        isPositive(value) {
          if (value <= 0) {
            throw new Error("排序必须是正整数");
          }
        },
      },
      content: DataTypes.TEXT,
    },
    {
      sequelize,
      modelName: "Article",
    }
  );
  return Article;
};

三、索引的添加queryInterface.addIndex

在这里插入图片描述

"use strict";
/** @type {import('sequelize-cli').Migration} */
module.exports = {
  async up(queryInterface, Sequelize) {
    await queryInterface.createTable("users", {
      id: {
        allowNull: false,
        autoIncrement: true,
        primaryKey: true,
        type: Sequelize.INTEGER.UNSIGNED,
      },
      avatar: {
        type: Sequelize.STRING,
      },
      username: {
        type: Sequelize.STRING,
      },
      nickname: {
        type: Sequelize.STRING,
      },
      email: {
        type: Sequelize.STRING,
      },
      sex: {
        type: Sequelize.STRING,
      },
      birthday: {
        type: Sequelize.DATE,
      },
      city: {
        type: Sequelize.STRING,
      },
      company: {
        type: Sequelize.STRING,
      },
      profession: {
        type: Sequelize.STRING,
      },
      workType: {
        type: Sequelize.STRING,
      },
      introduce: {
        type: Sequelize.STRING,
      },
      role: {
        type: Sequelize.TINYINT.UNSIGNED,
      },
      createdAt: {
        allowNull: false,
        type: Sequelize.DATE,
      },
      updatedAt: {
        allowNull: false,
        type: Sequelize.DATE,
      },
    });
    await queryInterface.addIndex("users", {
      fields: ["email"], // 要添加的索引字段
      unique: true, // 是否唯一索引
    });
    await queryInterface.addIndex("users", {
      fields: ["username"],
      unique: true,
    });
    await queryInterface.addIndex("users", {
      fields: ["role"],
      unique: true,
    });
  },
  async down(queryInterface, Sequelize) {
    await queryInterface.dropTable("users");
  },
};

三、新增表字段

1.在user表中新增phone字段

addColumn:新增
changeColumn:修改

sequelize migration:create --name add-phone-to-user
"use strict";

/** @type {import('sequelize-cli').Migration} */
module.exports = {
  async up(queryInterface, Sequelize) {
    // user 表中,新增phone字段
    await queryInterface.addColumn("users", "password", {
      type: Sequelize.STRING,
    });
  },

  async down(queryInterface, Sequelize) {
    await queryInterface.removeColumn("users", "password");
  },
};

在这里插入图片描述

2.运行迁移命令
sequelize db:migrate

在这里插入图片描述

3.在user模型中增加校验

在这里插入图片描述

对密码加密

1.安装
npm i  bcryptjs
2.使用

models/user.js文件中

"use strict";
const { Model } = require("sequelize");
// 引入
const bcryptjs = require("bcryptjs");
// 部分代码
password: {
  type: DataTypes.STRING,
  allowNull: false,
  validate: {
    notNull: { msg: "密码必须存在" },
    notEmpty: { msg: "密码不能为空" },
  },
  set(value) {
    if (value.length >= 6 && value.length <= 45) {
     //加密
      this.setDataValue("password", bcryptjs.hashSync(value, 10));
    } else {
      throw new Error("密码必须是6-45之间");
    }
  },
},
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值