安装依赖
npm install --save @nestjs/typeorm typeorm mysql2
TypeORM 的流程:
DataSource 里存放着数据库连接的配置,比如用户名、密码、驱动包、连接池配置等等。
而 Entity 里通过 @Entity、@PrimaryGeneratedColumn、@Column 等装饰器来建立数据库表的映射关系。
同时还有 Entity 之间的 @OneToOne、@OneToMany、@ManyToMany 的关系,这些会映射成数据库表通过外键、中间表来建立的关系。
DataSource.initialize 的时候,会和数据库服务建立连接,如果配置了 synchronize,还会生成建表 sql 语句来创建表。
DataSource 初始化之后就可以拿到 EntityManager 了,由它负责对各种 Entity 进行增删改查,比如 find、delete、save 等方法,还可以通过 query builder 来创建复杂的查询。
如果你只是想做对单个 Entity 的 CRUD,那可以拿到这个 Entity 的 Repository 类,它同样有上面的那些方法,只是只能用来操作单个 Entity。
这就是 TypeORM 的流程。
全局注册
在app.module.ts中增加
TypeOrmModule.forRootAsync({
imports: [ConfigModule],
inject: [ConfigService],
useFactory: async (configService: ConfigService) => {
return {
type: 'mysql',
connectorPackage: 'mysql2',
host: configService.get('DB_HOST'), // 主机,默认为localhost
port: configService.get<number>('DB_PORT'), // 端口号
username: configService.get('DB_USER'), // 用户名
password: configService.get('DB_PASSWORD'), // 密码
database: configService.get('DB_DATABASE'), //数据库名
entities: ['dist/**/*.entity{.ts,.js}'],
timezone: '+08:00', //服务器上配置的时区
synchronize: false, //根据实体自动创建数据库表, 生产环境建议关闭
autoLoadEntities: true,
};
},
}),
import { ConfigModule, ConfigService } from '@nestjs/config';
import envConfig from './config/env';
在imports中
ConfigModule.forRoot({
isGlobal: true, // 设置为全局
envFilePath: [envConfig.path], // .env 环境变量的路径,根据不同环境获取不同的文件
})
在 config/env.ts中
import * as fs from 'fs';
import * as path from 'path';
const isProd = process.env.NODE_ENV == 'prod';
function parseEnv() {
const localEnv = path.resolve('.env');
const prodEnv = path.resolve('.env.prod');
if (!fs.existsSync(localEnv) && !fs.existsSync(prodEnv)) {
throw new Error('缺少环境配置文件');
}
const filePath = isProd && fs.existsSync(prodEnv) ? prodEnv : localEnv;
return { path: filePath };
}
export default parseEnv();
运行时:
typeorm几种关系
用户和用户信息是一对一的关系
@OneToOne(() => User, user => user.profile)
user: User;
@OneToOne(() => Profile, profile => profile.user)
@JoinColumn()
profile: Profile;
一对一我们是通过 @OneToOne 和 @JoinColumn 来把 Entity 映射成数据库表
2.ManytoOne和OnetoMany
//合同entry
@ManyToOne(() => ContractType, (contractType) => contractType.contracts)
@JoinColumn({ name: 'contractTypeId' })
contractType: ContractType;
@OneToMany(() => Contract, (contract) => contract.contractType) //一个合同分类对应多个合同
contracts: Contract[];
如上,一个合同只有一个分类,但是一个合同分类下可以有多个合同
3. ManytoMany
一个合同可以有多个分类标签,一个标签也可以对应多个合同
//合同entry
@ManyToMany(() => Insurance, (insuranceType) => insuranceType.contracts)
@JoinTable({
name: 'contract_insurance_types',
joinColumn: { name: 'contractId', referencedColumnName: 'id' },
inverseJoinColumn: { name: 'insuranceTypeId', referencedColumnName: 'id' },
})
insuranceTypes: Insurance[];
//分类entry
@ManyToMany(() => Contract, (contract) => contract.insuranceTypes)
contracts: Contract[];
OnetoMany和ManytoMany查询使用
...
@InjectRepository(Contract) private docRepository:Repository<Contract>... 使用 const docQuery = await this.docRepository.createQueryBuilder('contract'); docQuery.leftJoinAndSelect('contract.contractType', 'contact_type'); docQuery.leftJoinAndSelect('contract.insuranceTypes', 'insurance'); docQuery.where('contract.id = :id', { id });
非特殊说明,本博所有文章均为博主原创。
如若转载,请注明出处:https://www.puxiaoshuai.top/?p=149