Sequelize 简介

什么是 Sequelize

  1. Sequelize 遵循基于承诺的 Node.js ORM 结构,适用于不同的数据库,如 PostgresMySQLMariaDBSQLiteMicrosoft SQL ServerSequelize 具有多种功能,使其易于实现和使用;

  2. Sequelize 的一些主要特点如下:

    • 它使用对象关系映射来映射对象,这就是为什么它被称为 ORM
    • Sequelize 支持可靠的事务支持以及急切和延迟加载的概念;
    • 它还可以对数据库执行读取复制;
    • Sequelize 遵循标准化,这意味着它在代码中有一个单一的模式定义,标准化使模式在进行更改时易于阅读和理解;

什么是 ORM

  1. 通过 ORM 框架,可以自动的把程序中的对象和数据库关联;

  2. ORM 框架会隐藏具体的数据库底层细节,让开发者使用同样的数据操作接口,完成对不同数据库的操作;

ORM 的优势

  1. 开发者不用关心数据库,仅需关心对象

  2. 可轻易的完成数据库的移植

  3. 无须拼接复杂的 sql 语句即可完成精确查询

Node 中的 ORM

  1. Sequelize 支持 jsts,比较成熟

  2. TypeORM 支持 ts,不成熟

模型定义和同步

案例:学校数据库

管理员

id 账号 密码 姓名

const sequelize = require("./db");
const { DataTypes } = require("sequelize");

// 创建一个模型对象
const Admin = sequelize.define(
  "Admin",
  {
    loginId: {
      type: DataTypes.STRING,
      allowNull: false,
    },
    loginPwd: {
      type: DataTypes.STRING,
      allowNull: false,
    },
  },
  {
    createdAt: false, // 不自动增加此列
    updatedAt: false, // 不自动增加此列
    paranoid: true // 从此以后,该表的数据不会真正的删除,而是增加一列 deletedAt,记录删除的时间
  }
);

module.exports = Admin;

班级

id 名称 开班时间

const sequelize = require("./db");
const { DataTypes } = require("sequelize");
const Student = require("./Student");
const Class = sequelize.define(
  "Class",
  {
    name: {
      type: DataTypes.STRING,
      allowNull: false,
    },
    openDate: {
      type: DataTypes.DATE,
      allowNull: false,
    },
  },
  {
    createdAt: false,
    updatedAt: false,
    paranoid: true,
  }
);

Class.hasMany(Student);

module.exports = Class;

学生

id 姓名 出生日期 性别 联系电话 所属班级

const sequelize = require("./db");
const { DataTypes } = require("sequelize");

module.exports = sequelize.define(
  "Student",
  {
    name: {
      type: DataTypes.STRING,
      allowNull: false,
    },
    birthdady: {
      type: DataTypes.DATE,
      allowNull: false,
    },
    sex: {
      type: DataTypes.BOOLEAN,
      allowNull: false,
    },
    mobile: {
      type: DataTypes.STRING(11),
      allowNull: false,
    }
  },
  {
    createdAt: false,
    updatedAt: false,
    paranoid: true,
  }
);

书籍

id 名称 图片 出版时间 作者

const sequelize = require("./db");
const { DataTypes } = require("sequelize");

module.exports = sequelize.define(
  "Book",
  {
    name: {
      type: DataTypes.STRING,
      allowNull: false,
    },
    imgurl: {
      type: DataTypes.STRING
    },
    publishDate: {
      type: DataTypes.STRING,
      allowNull: false,
    },
    author: {
      type: DataTypes.STRING,
      allowNull: false,
    }
  },
  {
    paranoid: true,
  }
);

同步模型

// 同步所有模型
require("./Admin");
require("./Book");
require("./Class");
require("./Student");
const sequelize = require("./db");

// 根据实体,自动创建表
sequelize.sync({ alter: true }).then(() => {
  console.log("所有模型同步完成");
});

连接数据库

const { Sequelize } = require("sequelize");

const sequelize = new Sequelize("myschooldb", "root", "123456.", {
  host: "localhost",
  dialect: "mysql",
  logging: null
});

module.exports = sequelize;

模型的增删改

管理员

// 管理员初始化
// 判断数据库中是否有管理员,如果没有,自动添加一个默认管理员
const Admin = require("../models/Admin");

exports.addAdmin = async function (adminObj) {
  // 应该判断 adminObj 的各种属性是否合理,以及账号是否已存在
  const ins = await Admin.create(adminObj);
  return ins.toJSON();
};

exports.deleteAdmin = async function (adminId) {
  // 方式1
  //   // 1.得到实例
  //   const ins = await Admin.findByPk(adminId);
  //   //   console.log(ins);
  //   // 2.删除实例
  //   if (ins) {
  //     await ins.destroy();
  //   }
  // 方式2
  const result = await Admin.destroy({
    where: {
      id: adminId,
    },
  });
  return result;
};

exports.updateAdmin = async function (id, adminObj) {
  // 方式1
  // // 1. 得到实例
  // const ins = await Admin.findByPk(id);
  // ins.loginId = adminObj.loginId;
  // // 2. 保存
  // ins.save();

  // 方式2
  const result = await Admin.update(adminObj, {
    where: {
      id,
    },
  });
  return result;
};

班级

const Class = require("../models/Class");
exports.addClass = async function (obj) {
  const ins = await Class.create(obj);
  return ins.toJSON();
};

exports.deleteClass = async function (id) {
  return await Class.destroy({
    where: {
      id,
    },
  });
};

exports.updateClass = async function (id, obj) {
  return await Class.update(obj, {
    where: {
      id,
    },
  });
};

学生

const Student = require("../models/Student");
exports.addStudent = async function (stuObj) {
  const ins = await Student.create(stuObj);
  return ins.toJSON();
};

exports.deleteStudent = async function (id) {
  return await Student.destroy({
    where: {
      id,
    },
  });
};

exports.updateStudent = async function (id, obj) {
  return await Student.update(obj, {
    where: {
      id,
    },
  });
};

书籍

const Book = require("../models/Book");
exports.addBook = async function (obj) {
  const ins = await Book.create(obj);
  return ins.toJSON();
};

exports.deleteBook = async function (id) {
  return await Book.destroy({
    where: {
      id,
    },
  });
};

exports.updateBook = async function (id, obj) {
  return await Book.update(obj, {
    where: {
      id,
    },
  });
};

模拟数据

利用 Mock.js 库生成数据

生成 class 数据

const Mock = require("mockjs");
const result = Mock.mock({
  "datas|16": [
    {
      "id|+1": 1,
      name: "前端第 @id 期",
      openDate: "@date",
    },
  ],
}).datas;

const Class = require("../models/Class");
Class.bulkCreate(result);

生成 student 数据

const Mock = require("mockjs");

const result = Mock.mock({
  "datas|500-700": [
    {
      name: "@cname",
      birthdady: "@date",
      "sex|1-2": true,
      mobile: /1\d{10}/,
      //   location: "@city(true)",
      "ClassId|1-16": 0,
    },
  ],
}).datas;
console.log(result);

const Student = require("../models/Student");
Student.bulkCreate(result);

数据抓取

  1. 抓取豆瓣读书中的书籍信息

  2. 涉及到的库

    • axios:发送一个 http 请求,得到服务器的响应结果,客户端和服务器通用;
    • cheerioJquery 的核心库,与 dom 无关;
// 抓取豆瓣读书中的数据信息
const axios = require("axios").default;
const cheerio = require("cheerio");
const Book = require("../models/Book");
/**
 * 获取豆瓣读书网页的源代码
 */
async function getBooksHTML() {
  const resp = await axios.get("https://book.douban.com/latest");
  return resp.data;
}

/**
 * 从豆瓣读书中得到一个完整的网页,并从网页中分析出书籍的基本信息,然后得到一个书籍的详情页链接数组
 */
async function getBookLinks() {
  const html = await getBooksHTML();
  const $ = cheerio.load(html);
  const achorElements = $("#content .grid-12-12 li a.cover");
  const links = achorElements
    .map((i, ele) => {
      const href = ele.attribs["href"];
      return href;
    })
    .get();
  return links;
}

/**
 * 根据书籍详情页的地址,得到该书籍的详细信息
 * @param {*} detailUrl
 */
async function getBookDetail(detailUrl) {
  const resp = await axios.get(detailUrl);
  const $ = cheerio.load(resp.data);
  const name = $("h1").text().trim();
  const imgurl = $("#mainpic .nbg img").attr("src");
  const spans = $("#info span.pl");
  const authorSpan = spans.filter((i, ele) => {
    return $(ele).text().includes("作者");
  });
  const author = authorSpan.next("a").text();
  const publishSpan = spans.filter((i, ele) => {
    return $(ele).text().includes("出版年");
  });
  const publishDate = publishSpan[0].nextSibling.nodeValue.trim();
  return {
    name,
    imgurl,
    publishDate,
    author,
  };
}

/**
 * 获取所有的书籍信息
 */
async function fetchAll() {
  const links = await getBookLinks(); //得到书籍的详情页地址
  const proms = links.map((link) => {
    return getBookDetail(link);
  });
  return Promise.all(proms);
}

/**
 * 得到书籍信息,然后保存到数据库
 */
async function saveToDB() {
  const books = await fetchAll();
  await Book.bulkCreate(books);
  console.log("抓取数据并保存到了数据库");
}

saveToDB();

数据查询

adminService

// 管理员初始化
// 判断数据库中是否有管理员,如果没有,自动添加一个默认管理员
const Admin = require("../models/Admin");
exports.addAdmin = async function (adminObj) {
  // 应该判断adminObj的各种属性是否合理,以及账号是否已存在
  const ins = await Admin.create(adminObj);
  return ins.toJSON();
};

exports.deleteAdmin = async function (adminId) {
  // 方式1
  //   // 1.得到实例
  //   const ins = await Admin.findByPk(adminId);
  //   //   console.log(ins);
  //   // 2.删除实例
  //   if (ins) {
  //     await ins.destroy();
  //   }
  // 方式2
  const result = await Admin.destroy({
    where: {
      id: adminId,
    },
  });
  return result;
};

exports.updateAdmin = async function (id, adminObj) {
  // 方式1
  // // 1. 得到实例
  // const ins = await Admin.findByPk(id);
  // ins.loginId = adminObj.loginId;
  // // 2. 保存
  // ins.save();

  // 方式2
  const result = await Admin.update(adminObj, {
    where: {
      id,
    },
  });
  return result;
};

exports.login = async function (loginId, loginPwd) {
  const result = await Admin.findOne({
    where: {
      loginId,
      loginPwd,
    },
  });
  if (result && result.loginId === loginId && result.loginPwd === loginPwd) {
    return result.toJSON();
  }
  return null;
};

exports.getAdminById = async function (id) {
  const result = await Admin.findByPk(id);
  if (result) {
    return result.toJSON();
  }
  return null;
};

exports.getAdmins = async function () {
  const result = await Admin.findAll();
  return JSON.parse(JSON.stringify(result));
};

bookService

const Book = require("../models/Book");
const { Op } = require("sequelize");
exports.addBook = async function (obj) {
  const ins = await Book.create(obj);
  return ins.toJSON();
};

exports.deleteBook = async function (id) {
  return await Book.destroy({
    where: {
      id,
    },
  });
};

exports.updateBook = async function (id, obj) {
  return await Book.update(obj, {
    where: {
      id,
    },
  });
};

exports.getBookById = async function (id) {
  const result = await Book.findByPk(id);
  if (result) {
    return result.toJSON();
  }
  return null;
};

exports.getBooks = async function (page = 1, limit = 10, keywords = "") {
  const result = await Student.findAndCountAll({
    attributes: ["id", "name", "sex", "birthdady"],
    where: {
      [Op.or]: [
        //里面的两个条件是或者关系
        {
          //条件1:姓名模糊匹配关键词
          name: {
            [Op.like]: `%${keywords}%`,
          },
        },
        {
          //条件2:作者模糊匹配关键词
          author: {
            [Op.like]: `%${keywords}%`,
          },
        },
      ],
    },
    offset: (page - 1) * limit,
    limit: +limit,
  });
  return {
    total: result.count,
    datas: JSON.parse(JSON.stringify(result.rows)),
  };
};

classService

const Class = require("../models/Class");
exports.addClass = async function (obj) {
  const ins = await Class.create(obj);
  return ins.toJSON();
};

exports.deleteClass = async function (id) {
  return await Class.destroy({
    where: {
      id,
    },
  });
};

exports.updateClass = async function (id, obj) {
  return await Class.update(obj, {
    where: {
      id,
    },
  });
};
exports.getClassById = async function (id) {
  const result = await Class.findByPk(id);
  if (result) {
    return result.toJSON();
  }
  return null;
};

exports.getClasses = async function () {
  const result = await Class.findAll();
  return JSON.parse(JSON.stringify(result));
};

studentService

const Student = require("../models/Student");
const { Op } = require("sequelize");
const Class = require("../models/Class");
exports.addStudent = async function (stuObj) {
  const ins = await Student.create(stuObj);
  return ins.toJSON();
};

exports.deleteStudent = async function (id) {
  return await Student.destroy({
    where: {
      id,
    },
  });
};

exports.updateStudent = async function (id, obj) {
  return await Student.update(obj, {
    where: {
      id,
    },
  });
};

exports.getStudentById = async function (id) {
  const result = await Student.findByPk(id);
  if (result) {
    return result.toJSON();
  }
  return null;
};

exports.getStudents = async function (
  page = 1,
  limit = 10,
  sex = -1,
  name = ""
) {
  // const results = await Student.findAll({
  //   offset: (page - 1) * limit,
  //   limit: +limit,
  // });
  // const total = await Student.count()
  // const datas = JSON.parse(JSON.stringify(results));
  // return {
  //   total,
  //   datas
  // }
  const where = {};
  if (sex !== -1) {
    where.sex = !!sex;
  }
  if (name) {
    where.name = {
      [Op.like]: `%${name}%`,
    };
  }

  const result = await Student.findAndCountAll({
    attributes: ["id", "name", "sex", "birthdady"],
    where,
    include: [Class],
    offset: (page - 1) * limit,
    limit: +limit,
  });
  return {
    total: result.count,
    datas: JSON.parse(JSON.stringify(result.rows)),
  };
};

附件下载

打赏作者
您的打赏是我前进的动力
微信
支付宝
评论

中午好👏🏻,我是 ✍🏻   疯狂 codding 中...

粽子

这有关于前端开发的技术文档和你分享。

相信你可以在这里找到对你有用的知识和教程。

了解更多

目录

  1. 1. Sequelize 简介
    1. 1.1. 什么是 Sequelize
    2. 1.2. 什么是 ORM
    3. 1.3. ORM 的优势
    4. 1.4. Node 中的 ORM
  2. 2. 模型定义和同步
    1. 2.1. 管理员
    2. 2.2. 班级
    3. 2.3. 学生
    4. 2.4. 书籍
    5. 2.5. 同步模型
    6. 2.6. 连接数据库
  3. 3. 模型的增删改
    1. 3.1. 管理员
    2. 3.2. 班级
    3. 3.3. 学生
    4. 3.4. 书籍
  4. 4. 模拟数据
    1. 4.1. 生成 class 数据
    2. 4.2. 生成 student 数据
  5. 5. 数据抓取
  6. 6. 数据查询
    1. 6.1. adminService
    2. 6.2. bookService
    3. 6.3. classService
    4. 6.4. studentService
  7. 7. 附件下载