如何基于纯领域类创建TypeORM实体,实现框架与业务解耦?
分离领域实体与TypeORM绑定逻辑的优雅实现
核心方案:使用TypeORM的EntitySchema
TypeORM原生提供了EntitySchema API,允许你在外部单独定义实体的数据库映射元数据,完全无需修改纯领域类,完美实现业务逻辑与框架绑定代码的关注点分离。
1. 保留纯领域实体类
维持你的纯业务逻辑实体,完全剥离任何框架相关代码:
export class Address { id: number; firstName: string; lastName: string; streetAddress1: string; }
2. 单独创建TypeORM映射配置
新建一个如address.entity-schema.ts的文件,通过EntitySchema定义数据库映射规则:
import { EntitySchema } from "typeorm"; import { Address } from "./address"; export const AddressSchema = new EntitySchema<Address>({ name: "Address", // 对应数据库表名 target: Address, // 关联到纯领域类 columns: { id: { type: "int", primary: true, generated: true, // 等价于@PrimaryGeneratedColumn装饰器 }, firstName: { type: "varchar", nullable: true, // 等价于@Column({ nullable: true }) }, lastName: { type: "varchar", nullable: true, }, streetAddress1: { type: "varchar", nullable: true, }, }, });
3. 在TypeORM配置中引入Schema
在你的TypeORM数据源配置(如data-source.ts)里,将AddressSchema加入entities数组:
import { DataSource } from "typeorm"; import { AddressSchema } from "./address.entity-schema"; export const AppDataSource = new DataSource({ type: "mysql", // 替换为你的数据库类型 host: "localhost", port: 3306, username: "root", password: "your_password", database: "test_db", entities: [AddressSchema], // 引入Schema而非实体类 synchronize: true, logging: false, });
4. 业务代码中直接使用纯领域类
在业务逻辑里,你依然可以直接操作Address类,TypeORM会通过Schema自动完成数据库映射:
import { AppDataSource } from "./data-source"; import { Address } from "./address"; const addressRepo = AppDataSource.getRepository(Address); // 创建并保存地址 const newAddr = new Address(); newAddr.firstName = "Alice"; newAddr.lastName = "Smith"; newAddr.streetAddress1 = "456 Oak Ave"; await addressRepo.save(newAddr); // 查询地址列表 const addrList = await addressRepo.find();
方案优势
- 彻底分离关注点:领域类只负责业务逻辑,数据库映射规则独立维护,不会污染业务代码。
- 无重复代码:无需创建重复的实体类(领域类+ORM实体类),复用同一个
Address类。 - 类型安全:
EntitySchema通过泛型绑定Address类型,配置过程中会触发TypeScript类型检查,避免字段名拼写错误。
内容的提问来源于stack exchange,提问作者SirKnigget
相关产品推荐
相关产品推荐

