TypeORM的使用

puxiaoshuai 2024-6-28 123 6/28

安装依赖

npm install --save @nestjs/typeorm typeorm mysql2

TypeORM 的流程:

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,
        };
      },
    }),
configService是动态从 env或者 prodEnv文件中进行读取。这种配置文件怎么读取了。使用自带的 ConfigService.
查看是否有@nestjs/config , 如果没有进行依赖安装 npm install --save @nestjs/config
在app.module.ts中也对config进行全局注册
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();

 

运行时:

"start": "NODE_ENV=development nest start",
"start:prod": "NODE_ENV=prod node dist/main", 就能使用不同环境的数据

typeorm几种关系

1.OneToOne的关系
用户和用户信息是一对一的关系
@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;
//合同类型entry   【正式合同/临时合同】
 @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 });

 

- THE END -

puxiaoshuai

6月28日16:54

最后修改:2024年6月28日
0

非特殊说明,本博所有文章均为博主原创。