You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

能否在NestJS中不使用TypeORM查询MySQL并执行原生SQL?

在NestJS中不借助ORM直接执行MySQL原生SQL查询

当然可以,你有两种主流方式实现:

方法1:通过TypeORM执行原生SQL

TypeORM本身支持原生SQL查询,不需要完全替换掉它。你可以利用EntityManager或QueryRunner来执行原生语句:

使用EntityManager.query()(基础场景)

import { Injectable } from '@nestjs/common';
import { InjectEntityManager } from '@nestjs/typeorm';
import { EntityManager } from 'typeorm';

@Injectable()
export class UserService {
  constructor(
    @InjectEntityManager() private readonly entityManager: EntityManager,
  ) {}

  async getUsers() {
    // 执行原生SELECT查询
    const users = await this.entityManager.query('SELECT * FROM users');
    return users;
  }

  async createUser(name: string, email: string) {
    // 用参数绑定防止SQL注入
    const result = await this.entityManager.query(
      'INSERT INTO users (name, email) VALUES (?, ?)',
      [name, email],
    );
    return result;
  }
}

使用QueryRunner(事务场景)

如果需要处理事务,QueryRunner是更合适的选择:

import { Injectable } from '@nestjs/common';
import { InjectConnection } from '@nestjs/typeorm';
import { Connection, QueryRunner } from 'typeorm';

@Injectable()
export class UserService {
  constructor(@InjectConnection() private readonly connection: Connection) {}

  async getUserWithTransaction(userId: number) {
    const queryRunner = this.connection.createQueryRunner();
    await queryRunner.connect();
    await queryRunner.startTransaction();

    try {
      const user = await queryRunner.query('SELECT * FROM users WHERE id = ?', [userId]);
      // 执行其他数据库操作...
      await queryRunner.commitTransaction();
      return user;
    } catch (err) {
      await queryRunner.rollbackTransaction();
      throw err;
    } finally {
      await queryRunner.release();
    }
  }
}

方法2:直接使用mysql2包连接(完全脱离ORM)

如果你想彻底不依赖ORM,可以直接用Node.js生态中常用的MySQL驱动mysql2:

步骤1:安装依赖

npm install mysql2

步骤2:创建数据库连接服务

import { Injectable, OnModuleInit, OnModuleDestroy } from '@nestjs/common';
import mysql from 'mysql2/promise';

@Injectable()
export class DatabaseService implements OnModuleInit, OnModuleDestroy {
  private connection: mysql.Connection;

  async onModuleInit() {
    this.connection = await mysql.createConnection({
      host: 'localhost',
      user: 'your_db_username',
      password: 'your_db_password',
      database: 'your_db_name',
    });
  }

  async onModuleDestroy() {
    await this.connection.end();
  }

  // 封装通用查询方法
  async query(sql: string, params?: any[]) {
    const [rows] = await this.connection.execute(sql, params);
    return rows;
  }
}

步骤3:在业务服务中调用

import { Injectable } from '@nestjs/common';
import { DatabaseService } from './database.service';

@Injectable()
export class UserService {
  constructor(private readonly dbService: DatabaseService) {}

  async getUsers() {
    const users = await this.dbService.query('SELECT * FROM users');
    return users;
  }
}

注意事项

  • 无论哪种方式,务必使用参数绑定,绝对不要直接将用户输入拼接进SQL语句,避免SQL注入风险。
  • 生产环境中,使用mysql2时建议用连接池(mysql.createPool())代替单连接,提升性能和稳定性。

内容的提问来源于stack exchange,提问作者William Pineda MHA

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 12:15:39