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

如何在Node.js中使用TypeORM连接Oracle数据库及将db.js迁移为TS

TypeORM连接Oracle云自治数据库解决方案

你当前TypeORM连接失败的核心原因有两个:

  1. 未在初始化连接前调用oracledb.initOracleClient()加载本地Oracle Instant Client
  2. 连接配置缺失必要的自治库连接参数,Oracle云自治数据库需要匹配TNS别名或完整连接串配置

修正后的TypeORM代码(兼容0.2.x版本)

import { createConnection } from "typeorm";
import oracledb from "oracledb";
// 可直接复用你原有可用的dbconfig配置
import dbConfig from "./dbconfig";

// 必须先初始化Oracle客户端,再创建连接
oracledb.initOracleClient({
  libDir: process.env.ORACLE_CLIENT_PATH || "D:\\MaterialSkywork\\Oracle\\instantclient_21_3"
});

createConnection({
  type: "oracle",
  username: dbConfig.user,
  password: dbConfig.password,
  // 自治数据库的TNS别名,对应你钱包中tnsnames.ora里的DBxxx_high配置
  connectString: dbConfig.connectString,
  synchronize: process.env.NODE_ENV === "development", // 生产环境务必关闭
  logging: process.env.NODE_ENV === "development",
  // 额外oracledb配置可放在extra中
  extra: {
    autoCommit: false
  }
}).then(connection => {
  console.log('数据库连接成功')
}).catch(error => console.log('连接失败:', error));

如果你使用的是TypeORM 0.3.x及以上版本,createConnection已废弃,请改用DataSource初始化:

import { DataSource } from "typeorm";
import oracledb from "oracledb";
import dbConfig from "./dbconfig";

oracledb.initOracleClient({
  libDir: process.env.ORACLE_CLIENT_PATH || "D:\\MaterialSkywork\\Oracle\\instantclient_21_3"
});

export const AppDataSource = new DataSource({
  type: "oracle",
  username: dbConfig.user,
  password: dbConfig.password,
  connectString: dbConfig.connectString,
  synchronize: process.env.NODE_ENV === "development",
  logging: process.env.NODE_ENV === "development",
  entities: [/* 你的实体类路径 */]
})

// 初始化连接
AppDataSource.initialize()
  .then(() => console.log('数据库连接成功'))
  .catch(err => console.error('连接失败:', err))

原生db.js迁移TypeScript方案

如果暂时不使用TypeORM,可按以下方案将原有可用的js代码转为TS:

  1. 首先安装类型依赖:npm install @types/oracledb --save-dev
  2. 编写db.ts文件:
import oracledb, { BindParameters, Result } from "oracledb";
import dbConfig from "./dbconfig";
import dotenv from "dotenv";
dotenv.config();

// 初始化Oracle客户端
oracledb.initOracleClient({
  libDir: process.env.ORACLE_CLIENT_PATH || "D:\\MaterialSkywork\\Oracle\\instantclient_21_3"
});

// 初始化连接池(比每次新建连接性能更高)
async function initPool() {
  await oracledb.createPool({
    ...dbConfig,
    poolMin: 2,
    poolMax: 10,
    poolIncrement: 1
  });
}
initPool().catch(err => console.error('连接池初始化失败:', err));

/**
 * 执行SQL查询
 * @param sql SQL语句
 * @param binds 绑定参数,避免SQL注入
 * @param autoCommit 是否自动提交
 */
export async function Open<T = any>(sql: string, binds: BindParameters = [], autoCommit: boolean = false): Promise<Result<T>> {
  let connection;
  try {
    // 从连接池获取连接
    connection = await oracledb.getConnection();
    // 配置返回格式为对象,无需手动按下标映射字段
    return await connection.execute<T>(sql, binds, {
      autoCommit,
      outFormat: oracledb.OUT_FORMAT_OBJECT
    });
  } finally {
    if (connection) {
      // 确保连接释放回连接池
      await connection.close();
    }
  }
}

迁移后你的业务查询代码可以简化为:

import { Open } from './db';

async function start() {
  const sql = "select * from elopez.orders";
  const result = await Open(sql, [], false);
  // 直接返回对象数组,无需手动映射
  const orders = result.rows;
  console.log(orders);
}
start();

最佳实践建议
  • 安全类
    • 绝对不要在生产环境开启synchronize: true,该配置会自动根据实体类修改数据库表结构,存在数据丢失风险
    • 敏感信息(密码、客户端路径、TNS配置路径)不要硬编码在代码中,使用dotenv加载.env文件配置,.env文件不要提交到代码仓库
    • 所有SQL查询必须使用参数绑定(即你原有代码中的binds参数),禁止拼接SQL字符串,避免SQL注入漏洞
    • 业务代码不要使用admin账号连接数据库,按需创建权限最小化的业务账号
  • 性能稳定性类
    • 推荐使用连接池管理数据库连接,避免每次请求新建/销毁连接的性能开销,同时控制连接数上限避免数据库压力过大
    • 所有数据库操作必须添加异常捕获,使用try/finally确保连接正常释放,避免连接泄漏
  • 工程化类
    • Oracle客户端路径根据不同环境(Windows/Mac/Linux)通过环境变量配置,不要硬编码固定路径
    • 查询时开启outFormat: oracledb.OUT_FORMAT_OBJECT直接返回键值对对象,避免按下标取值出现字段匹配错误

内容的提问来源于stack exchange,提问作者Edisson Gabriel López

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 18:15:07