Nest.js с нуля до одной серии (два): используйте Sequelize, чтобы управлять базой данных

Node.js

предисловие

В прошлой статье было рассказано, как создать проект, маршрутизировать доступ и как создать модуль, в этой статье речь пойдет о подключении и использовании базы данных.

Поскольку это back-end проект, конечно, он должен иметь возможность подключаться к базе данных, иначе лучше писать статические страницы напрямую.

В этом руководстве используется MySQL, и может возникнуть вопрос, почему бы не использовать MongoDB. . . Ух, так как компания использует MySQL, я тоже написал туториал, исходя из опыта проекта MongoDB не ступил на яму, так что не буду тут детей вводить в заблуждение.

Адрес проекта GitHub, Добро пожаловать в Звезду больших парней.

1. Подготовка MySQL

Прежде всего, убедитесь, что у вас есть база данных для подключения.Если нет, вы можете загрузить ее с официального сайта MySQL и запустить локально. Учебник по установке здесь описываться не будет, «Baidu, вы будете знать».

Для управления базой данных рекомендуется использовать инструмент визуализации Navicat Premium.

После подключения к базе данных с помощью Navicat создайте новую библиотеку:

Нажмите на библиотеку, которую мы только что создалиnest_zero_to_one, нажмите «Таблицы» и обнаружите, что она пуста. Затем мы создаем новую таблицу, нажимаем «Запрос» на панели инструментов выше и добавляем новый запрос:

Скопируйте следующий код в поле и нажмите «Выполнить» выше, чтобы завершить создание таблицы:

CREATE TABLE `admin_user` (
  `user_id` smallint(6) NOT NULL AUTO_INCREMENT COMMENT '用户ID',
  `account_name` varchar(24) NOT NULL COMMENT '用户账号',
  `real_name` varchar(20) NOT NULL COMMENT '真实姓名',
  `passwd` char(32) NOT NULL COMMENT '密码',
  `passwd_salt` char(6) NOT NULL COMMENT '密码盐',
  `mobile` varchar(15) NOT NULL DEFAULT '0' COMMENT '手机号码',
  `role` tinyint(4) NOT NULL DEFAULT '3' COMMENT '用户角色:0-超级管理员|1-管理员|2-开发&测试&运营|3-普通用户(只能查看)',
  `user_status` tinyint(4) NOT NULL DEFAULT '0' COMMENT '状态:0-失效|1-有效|2-删除',
  `create_by` smallint(6) NOT NULL COMMENT '创建人ID',
  `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `update_by` smallint(6) NOT NULL DEFAULT '0' COMMENT '修改人ID',
  `update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
  PRIMARY KEY (`user_id`),
  KEY `idx_m` (`mobile`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT='后台用户表';

Тогда мы увидим, что слеваTablesболееadmin_userТаблица, нажмите, чтобы увидеть информацию о поле:

Сначала мы случайно вставляем 2 фрагмента данных, чтобы облегчить последующие запросы:

Во-вторых, конфигурация базы данных проекта

Сначала создайте папку в корневом каталоге проектаconfigsrcsiblings), предназначенный для размещения различных конфигураций.

Затем создайте новый файлdb.ts:

// config/db.ts
const productConfig = {
  mysql: {
    port: '数据库端口',
    host: '数据库地址',
    user: '用户名',
    password: '密码',
    database: 'nest_zero_to_one', // 库名
    connectionLimit: 10, // 连接限制
  },
};

const localConfig = {
  mysql: {
    port: '数据库端口',
    host: '数据库地址',
    user: '用户名',
    password: '密码',
    database: 'nest_zero_to_one', // 库名
    connectionLimit: 10, // 连接限制
  },
};

// 本地运行是没有 process.env.NODE_ENV 的,借此来区分[开发环境]和[生产环境]
const config = process.env.NODE_ENV ? productConfig : localConfig;

export default config;

Ps: Этот файл не синхронизирован с github, и читатели должны настроить его в соответствии с реальной ситуацией

Есть много инструментов, подключенных к базе данных, я использовал здесьSequelize, сначала установите зависимости:

$ npm i sequelize sequelize-typescript mysql2 -S
或
$ yarn add sequelize sequelize-typescript mysql2 -S

затем вsrcСоздать папку в каталогеdatabase, Затем создайтеsequelize.ts:

// src/database/sequelize.ts
import { Sequelize } from 'sequelize-typescript';
import db from '../../config/db';

const sequelize = new Sequelize(db.mysql.database, db.mysql.user, db.mysql.password || null, {
  // 自定义主机; 默认值: localhost
  host: db.mysql.host, // 数据库地址
  // 自定义端口; 默认值: 3306
  port: db.mysql.port,
  dialect: 'mysql',
  pool: {
    max: db.mysql.connectionLimit, // 连接池中最大连接数量
    min: 0, // 连接池中最小连接数量
    acquire: 30000,
    idle: 10000, // 如果一个线程 10 秒钟内没有被使用过的话,那么就释放线程
  },
  timezone: '+08:00', // 东八时区
});

// 测试数据库链接
sequelize
  .authenticate()
  .then(() => {
    console.log('数据库连接成功');
  })
  .catch((err: any) => {
    // 数据库连接失败时打印输出
    console.error(err);
    throw err;
  });

export default sequelize;

3. Тест подключения к базе данных

Хорошо, давайте проверим соединение с базой данных.

мы переписываемuser.service.tsЛогика:

// src/logical/user/user.service.ts
import { Injectable } from '@nestjs/common';
import * as Sequelize from 'sequelize'; // 引入 Sequelize 库
import sequelize from '../../database/sequelize'; // 引入 Sequelize 实例

@Injectable()
export class UserService {
  async findOne(username: string): Promise<any | undefined> {
    const sql = `
      SELECT
        user_id id, real_name realName, role
      FROM
        admin_user
      WHERE
        account_name = '${username}'
    `; // 一段平淡无奇的 SQL 查询语句
    try {
      const res = await sequelize.query(sql, {
        type: Sequelize.QueryTypes.SELECT, // 查询方式
        raw: true, // 是否使用数组组装的方式展示结果
        logging: true, // 是否将 SQL 语句打印到控制台,默认为 true
      });
      const user = res[0]; // 查出来的结果是一个数组,我们只取第一个。
      if (user) {
        return {
          code: 200, // 返回状态码,可自定义
          data: {
            user,
          },
          msg: 'Success',
        };
      } else {
        return {
          code: 600,
          msg: '查无此人',
        };
      }
    } catch (error) {
      return {
        code: 503,
        msg: `Service error: ${error}`,
      };
    }
  }
}

Сохраните файл, и вы увидите обновленную консоль (при условии, что вы используетеyarn start:devНачните) и распечатайте следующее утверждение:

Это говорит о том, что предыдущая конфигурация вступила в силу, попробуем запросить интерфейс с прежними параметрами:

Возвращает «Нет такого человека», указывая на то, что в базе данных нет пользователя с именем «Малыш».

Давайте изменим правильное существующее имя пользователя и попробуем еще раз:

Затем наблюдайте за консолью, наш оператор запроса был распечатан черезlogging: true, вы можете найти ошибки операторов SQL более четко при отладке ошибок, но рекомендуется после того, как тест станет стабильным, закрыть его перед выходом в онлайн, иначе записанные журналы будут очень сложными:

Затем сравните таблицы в базе данных и обнаружите, что найденные данные согласуются с данными в базе данных.На этом тест подключения к MySQL завершен, и вы можете с радостью перемещать кирпичи в Службе в будущем.

Суммировать

Это знакомит с подготовкой данных MySQL, конфигурацией Sequelize, подключением Nest, как MySQL через Sequelize, и с простым запросом для проверки соединения.

это здесь,Настоятельно рекомендуется использовать собственные операторы SQL для работы с базой данных..

Хотя Sequelize предоставляет множество удобных методов, вы можете перейти кОфициальная документация Sequelize v5Просмотрите, чтобы узнать. Но автор отмечаетloggingНапечатанное утверждение обнаружило, что на самом деле существует много ненужных операций, которые слишком много влияют на производительность в случае высокого параллелизма.

И если вы не используете собственные запросы, вам нужно сопоставлять объекты с таблицами базы данных, а затем каждый раз, когда инструмент обновляется, требуется время и затраты на обучение.Если база данных меняет поля, отношение сопоставления будет неправильным, и то проект будет сообщать о бредовых ошибках простоя (личный опыт).

С собственным SQL вам нужно выучить только один язык, и вы можете использовать другой инструмент, и даже если вы измените поле, вы только сообщите об ошибке при запросе интерфейса, а затем вы можете изменить его для этого оператора, и Теперь, когда функция поиска и замены настолько мощна, пакетная модификация не представляет сложности.

Самое главное, если вы переходите от внешнего интерфейса к внутреннему или просто от нулевого основания к внутреннему, рекомендуется сначала заложить прочный фундамент для SQL, иначе он будетJOIN,LEFT JOINиRIGHT JOINРазница не ясна (у нашей компании есть затворные с тремя годами опыта, используйте егоLEFT JOIN,然后被 DB 主管一顿痛骂。 . . Настоящая вещь).

Больше написания, больше анализа, больше просмотров ошибок консоли и больше соображений производительности — это самый быстрый способ начать работу.

Примечание: при написании оператора обновления UPDATE обязательно добавьте условие WHERE, обязательно добавьте условие WHERE, обязательно добавьте условие WHERE, скажите важные вещи 3 раза, уроки из крови и слез! ! !

В следующей статье будет рассказано, как использовать JWT (Json Web Token) для единого входа.

Эта статья записана вПрактическое руководство по NestJS, следите за новыми статьями.

`