导读:本期聚焦于木下创作的《如何在TypeScript中使用TypeORM连接和操作PostgreSQL数据库?》,敬请观看详情。TypeORM是Node.js生态中一款成熟的ORM框架,配合TypeScript的装饰器语法,可以让我们以面向对象的方式操作PostgreSQL数据库。本文从环境搭建入手,讲解如何安装依赖、配置数据源、定义实体以及建立与PostgreSQL的连接,随后演示常用的一对多、多对多关系映射写法,并结合Repository和QueryBuilder两种查询方式给出增删改查的完整示例。文中还总结了连接池参数调优、事务处理以及常见报错的排查思路,帮助开发者在实际项目中少走弯路。

TypeORM是目前TypeScript生态中使用最广泛的ORM框架之一,它支持装饰器语法,可以把数据库中的表映射成TypeScript中的类,让开发者用面向对象的方式操作PostgreSQL,而不必手写大量SQL。这篇文章将从零开始搭建一个TypeScript加PostgreSQL的项目,覆盖数据源配置、实体定义、关系映射和常用查询写法,并分享一些实际项目中容易踩到的坑。

如何在TypeScript中使用TypeORM连接和操作PostgreSQL数据库?

一、环境搭建与数据源配置

首先需要准备一个可用的PostgreSQL实例,可以是本地安装的,也可以使用Docker快速启动一个。接着初始化一个TypeScript项目并安装依赖,最常用的组合是typeormpg驱动以及reflect-metadata

npm init -y
npm install typeorm pg reflect-metadata
npm install -D typescript ts-node @types/node
npx tsc --init

TypeORM依赖装饰器元数据,所以必须在应用入口的最顶部引入reflect-metadata,并且在tsconfig.json中启用两个关键选项:experimentalDecoratorsemitDecoratorMetadata。如果漏掉这一步,运行时会抛出类似“Experimental support for decorators is a feature that is subject to change”的错误,这是新手最常见的问题之一。

接下来配置数据源。TypeORM提供了DataSource类来管理数据库连接,推荐把它单独放在一个文件中导出,方便其他模块复用:

import "reflect-metadata";
import { DataSource } from "typeorm";

export const AppDataSource = new DataSource({
  type: "postgres",
  host: "localhost",
  port: 5432,
  username: "postgres",
  password: "123456",
  database: "test_db",
  synchronize: false, // 生产环境务必关闭
  logging: true,
  entities: ["src/entity/**/*.ts"],
  poolSize: 10,
});

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

这里有几个参数值得注意。synchronize设为true时,TypeORM会自动根据实体结构同步建表,开发阶段很方便,但生产环境千万不要开启,因为它的同步逻辑比较粗暴,可能造成数据丢失。生产环境建议使用migration迁移脚本管理表结构。另外poolSize控制连接池大小,默认是10,高并发场景下可以根据数据库的最大连接数合理调整,通常应用实例数乘以poolSize要小于PostgreSQL的max_connections配置。

二、实体定义与关系映射

实体是TypeORM的核心概念,一个类对应一张表,类的属性对应表的列。使用@Entity装饰器标记类,用@PrimaryGeneratedColumn@Column等装饰器描述列:

import {
  Entity, PrimaryGeneratedColumn, Column,
  CreateDateColumn, UpdateDateColumn,
} from "typeorm";

@Entity("users")
export class User {
  @PrimaryGeneratedColumn()
  id: number;

  @Column({ length: 50, unique: true })
  username: string;

  @Column({ type: "varchar", length: 100, select: false })
  password: string;

  @Column({ type: "int", default: 0 })
  age: number;

  @CreateDateColumn()
  createdAt: Date;

  @UpdateDateColumn()
  updatedAt: Date;
}

实体定义中有很多细节可以优化。select: false可以让该字段默认不出现在查询结果里,密码这类敏感字段建议加上。日期字段推荐使用@CreateDateColumn@UpdateDateColumn,TypeORM会自动维护时间戳。PostgreSQL特有的JSON类型也很实用,直接声明type: "jsonb"就能存储结构化数据。

实际项目中表之间必然存在关联。TypeORM通过@OneToMany@ManyToOne@OneToOne@ManyToMany四个装饰器处理关系。以用户和文章的一对多关系为例:

@Entity("articles")
export class Article {
  @PrimaryGeneratedColumn()
  id: number;

  @Column({ length: 100 })
  title: string;

  @Column({ type: "text" })
  content: string;

  // 多篇文章属于一个作者
  @ManyToOne(() => User, (user) => user.articles)
  author: User;

  @Column()
  authorId: number;
}

// User实体中补充反向关系
// @OneToMany(() => Article, (article) => article.author)
// articles: Article[];

写关系映射时建议总是把外键列(如authorId)显式声明出来,这样在创建关联数据时可以直接设置ID而不必先查询出完整的关联对象,减少一次数据库往返。查询时配合relations选项或QueryBuilderleftJoinAndSelect即可一次性取出关联数据,避免N加1查询问题。

三、增删改查与事务处理

TypeORM提供两种主流查询方式:Repository模式和QueryBuilder模式。Repository封装了findfindOnesaveremove等便捷方法,适合大多数常规场景:

import { AppDataSource } from "./data-source";
import { User } from "./entity/User";

const userRepo = AppDataSource.getRepository(User);

// 新增
const user = await userRepo.save({
  username: "zhangsan",
  password: "hashed_pwd",
  age: 25,
});

// 条件查询
const found = await userRepo.find({
  where: { age: 25 },
  order: { createdAt: "DESC" },
  take: 10,
  skip: 0,
});

// 更新
await userRepo.update({ id: 1 }, { age: 26 });

// 删除
await userRepo.delete(1);

当查询逻辑复杂时,QueryBuilder更灵活,它支持多表连接、子查询、聚合函数和原生SQL片段。需要注意getOne返回可能为null,TypeScript中要做好空值判断:

const result = await AppDataSource
  .createQueryBuilder(User, "u")
  .leftJoinAndSelect("u.articles", "a")
  .where("u.age > :age", { age: 18 })
  .andWhere("a.title ILIKE :kw", { kw: "%typeorm%" })
  .orderBy("u.id", "ASC")
  .getMany();

涉及多表写入的操作必须使用事务保证一致性。TypeORM的事务API有三种写法,推荐使用transaction方法的回调形式,出现异常时自动回滚:

await AppDataSource.transaction(async (manager) => {
  const user = await manager.save(User, {
    username: "lisi",
    password: "hashed_pwd",
  });

  await manager.save(Article, {
    title: "第一篇文章",
    content: "正文内容",
    authorId: user.id,
  });
});

最后提醒几个容易出错的地方:一是连接失败时优先检查PostgreSQL的pg_hba.conf认证配置;二是save方法带有主键时会执行更新,如果想强制插入请用insert;三是软删除可以配合@DeleteDateColumn使用,调用softDelete后数据不会物理删除,查询时默认被过滤。掌握这些要点后,用TypeORM开发PostgreSQL应用会顺畅很多。

TypeORMPostgreSQLTypeScript修改时间:2026-09-03 06:34:50

免责声明:已尽一切努力确保本网站所含信息的准确性。网站作品多为原创整理与精心创作,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们进行处理Email:chomcom@qq.com。
引用或转载本作品时,请注明当前出处:https://www.ipipp.com/html/20260903/49389.html,基于非商业用途的前提下,欢迎转载或二创本作品。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。