You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
@@ -13,11 +13,9 @@ For integrating with SQL and NoSQL databases, Nest provides the `@nestjs/typeorm
13
13
To begin using it, we first install the required dependencies. In this chapter, we'll demonstrate using the popular [MySQL](https://www.mysql.com/) Relational DBMS, but TypeORM provides support for many relational databases, such as PostgreSQL, Oracle, Microsoft SQL Server, SQLite, and even NoSQL databases like MongoDB. The procedure we walk through in this chapter will be the same for any database supported by TypeORM. You'll simply need to install the associated client API libraries for your selected database.
> warning **Warning** Note that we're using TypeORM v0.2, which isn't the latest version of TypeORM. The latter has substantial modifications and duplicate methods which are used on this page. You can read about `[email protected]` changes [on their repository](https://github.com/typeorm/typeorm/releases/tag/0.3.0).
20
-
21
19
Once the installation process is complete, we can import the `TypeOrmModule` into the root `AppModule`.
22
20
23
21
```typescript
@@ -44,7 +42,7 @@ export class AppModule {}
44
42
45
43
> warning **Warning** Setting `synchronize: true` shouldn't be used in production - otherwise you can lose production data.
46
44
47
-
The `forRoot()` method supports all the configuration properties exposed by the `createConnection()` function from the [TypeORM](https://typeorm.io/#/connection-options) package. In addition, there are several extra configuration properties described below.
45
+
The `forRoot()` method supports all the configuration properties exposed by the `DataSource` constructor from the [TypeORM](https://typeorm.io/data-source-options#common-data-source-options) package. In addition, there are several extra configuration properties described below.
48
46
49
47
<table>
50
48
<tr>
@@ -65,78 +63,37 @@ The `forRoot()` method supports all the configuration properties exposed by the
65
63
</tr>
66
64
</table>
67
65
68
-
> info **Hint** Learn more about the connection options [here](https://typeorm.io/#/connection-options).
69
-
70
-
Alternatively, rather than passing a configuration object to `forRoot()`, we can create an `ormconfig.json` file in the project root directory.
71
-
72
-
```json
73
-
{
74
-
"type": "mysql",
75
-
"host": "localhost",
76
-
"port": 3306,
77
-
"username": "root",
78
-
"password": "root",
79
-
"database": "test",
80
-
"entities": ["dist/**/*.entity{.ts,.js}"],
81
-
"synchronize": true
82
-
}
83
-
```
84
-
85
-
Then, we can call `forRoot()` without any options:
86
-
87
-
```typescript
88
-
@@filename(app.module)
89
-
import { Module } from'@nestjs/common';
90
-
import { TypeOrmModule } from'@nestjs/typeorm';
91
-
92
-
@Module({
93
-
imports: [TypeOrmModule.forRoot()],
94
-
})
95
-
exportclassAppModule {}
96
-
```
97
-
98
-
> warning **Warning** Static glob paths (e.g., `dist/**/*.entity{{ '{' }} .ts,.js{{ '}' }}`) won't work properly with [webpack](https://webpack.js.org/).
66
+
> info **Hint** Learn more about the data source options [here](https://typeorm.io/data-source-options).
99
67
100
-
> info **Hint** Note that the `ormconfig.json` file is loaded by the `typeorm` library. Thus, any of the extra properties described above (which are supported internally by way of the `forRoot()` method - for example, `autoLoadEntities` and `retryDelay`) won't be applied. Luckily, TypeORM provides the [`getConnectionOptions`](https://typeorm.io/#/using-ormconfig/overriding-options-defined-in-ormconfig) function that reads connection options from the `ormconfig` file or environment variables. With this, you can still use the configuration file and set Nest-specific options, as follows:
101
-
>
102
-
> ```typescript
103
-
>TypeOrmModule.forRootAsync({
104
-
> useFactory: async () =>
105
-
>Object.assign(awaitgetConnectionOptions(), {
106
-
> autoLoadEntities: true,
107
-
> }),
108
-
> });
109
-
>```
110
-
111
-
Once this is done, the TypeORM `Connection` and `EntityManager` objects will be available to inject across the entire project (without needing to import any modules), for example:
68
+
Once this is done, the TypeORM `DataSource` and `EntityManager` objects will be available to inject across the entire project (without needing to import any modules), for example:
112
69
113
70
```typescript
114
71
@@filename(app.module)
115
-
import { Connection } from'typeorm';
72
+
import { DataSource } from'typeorm';
116
73
117
74
@Module({
118
75
imports: [TypeOrmModule.forRoot(), UsersModule],
119
76
})
120
77
exportclassAppModule {
121
-
constructor(privateconnection:Connection) {}
78
+
constructor(privatedataSource:DataSource) {}
122
79
}
123
80
@@switch
124
-
import { Connection } from'typeorm';
81
+
import { DataSource } from'typeorm';
125
82
126
-
@Dependencies(Connection)
83
+
@Dependencies(DataSource)
127
84
@Module({
128
85
imports: [TypeOrmModule.forRoot(), UsersModule],
129
86
})
130
87
exportclassAppModule {
131
-
constructor(connection) {
132
-
this.connection=connection;
88
+
constructor(dataSource) {
89
+
this.dataSource=dataSource;
133
90
}
134
91
}
135
92
```
136
93
137
94
#### Repository pattern
138
95
139
-
[TypeORM](https://github.com/typeorm/typeorm) supports the **repository design pattern**, so each entity has its own repository. These repositories can be obtained from the database connection.
96
+
[TypeORM](https://github.com/typeorm/typeorm) supports the **repository design pattern**, so each entity has its own repository. These repositories can be obtained from the database data source.
140
97
141
98
To continue the example, we need at least one entity. Let's define the `User` entity.
142
99
@@ -347,9 +304,7 @@ export class User {
347
304
348
305
#### Auto-load entities
349
306
350
-
Manually adding entities to the `entities` array of the connection options can be tedious. In addition, referencing entities from the root module breaks application domain boundaries and causes leaking implementation details to other parts of the application. To solve this issue, static glob paths can be used (e.g., `dist/**/*.entity{{ '{' }} .ts,.js{{ '}' }}`).
351
-
352
-
Note, however, that glob paths are not supported by webpack, so if you are building your application within a monorepo, you won't be able to use them. To address this issue, an alternative solution is provided. To automatically load entities, set the `autoLoadEntities` property of the configuration object (passed into the `forRoot()` method) to `true`, as shown below:
307
+
Manually adding entities to the `entities` array of the data source options can be tedious. In addition, referencing entities from the root module breaks application domain boundaries and causes leaking implementation details to other parts of the application. To address this issue, an alternative solution is provided. To automatically load entities, set the `autoLoadEntities` property of the configuration object (passed into the `forRoot()` method) to `true`, as shown below:
353
308
354
309
```typescript
355
310
@@filename(app.module)
@@ -434,22 +389,22 @@ A database transaction symbolizes a unit of work performed within a database man
434
389
435
390
There are many different strategies to handle [TypeORM transactions](https://typeorm.io/#/transactions). We recommend using the `QueryRunner` class because it gives full control over the transaction.
436
391
437
-
First, we need to inject the `Connection` object into a class in the normal way:
392
+
First, we need to inject the `DataSource` object into a class in the normal way:
438
393
439
394
```typescript
440
395
@Injectable()
441
396
exportclassUsersService {
442
-
constructor(privateconnection:Connection) {}
397
+
constructor(privatedataSource:DataSource) {}
443
398
}
444
399
```
445
400
446
-
> info **Hint** The `Connection` class is imported from the `typeorm` package.
401
+
> info **Hint** The `DataSource` class is imported from the `typeorm` package.
447
402
448
403
Now, we can use this object to create a transaction.
> info **Hint** Note that the `connection` is used only to create the `QueryRunner`. However, to test this class would require mocking the entire `Connection` object (which exposes several methods). Thus, we recommend using a helper factory class (e.g., `QueryRunnerFactory`) and defining an interface with a limited set of methods required to maintain transactions. This technique makes mocking these methods pretty straightforward.
426
+
> info **Hint** Note that the `dataSource` is used only to create the `QueryRunner`. However, to test this class would require mocking the entire `DataSource` object (which exposes several methods). Thus, we recommend using a helper factory class (e.g., `QueryRunnerFactory`) and defining an interface with a limited set of methods required to maintain transactions. This technique makes mocking these methods pretty straightforward.
472
427
473
-
Alternatively, you can use the callback-style approach with the `transaction` method of the `Connection` object ([read more](https://typeorm.io/#/transactions/creating-and-using-transactions)).
428
+
Alternatively, you can use the callback-style approach with the `transaction` method of the `DataSource` object ([read more](https://typeorm.io/#/transactions/creating-and-using-transactions)).
474
429
475
430
```typescript
476
431
asynccreateMany(users: User[]) {
477
-
awaitthis.connection.transaction(asyncmanager=> {
432
+
awaitthis.dataSource.transaction(asyncmanager=> {
478
433
awaitmanager.save(users[0]);
479
434
awaitmanager.save(users[1]);
480
435
});
@@ -491,7 +446,7 @@ With TypeORM [subscribers](https://typeorm.io/#/listeners-and-subscribers/what-i
491
446
492
447
```typescript
493
448
import {
494
-
Connection,
449
+
DataSource,
495
450
EntitySubscriberInterface,
496
451
EventSubscriber,
497
452
InsertEvent,
@@ -500,8 +455,8 @@ import { User } from './user.entity';
@@ -544,7 +499,7 @@ Migration classes are separate from the Nest application source code. Their life
544
499
545
500
#### Multiple databases
546
501
547
-
Some projects require multiple database connections. This can also be achieved with this module. To work with multiple connections, first create the connections. In this case, connection naming becomes **mandatory**.
502
+
Some projects require multiple database connections. This can also be achieved with this module. To work with multiple connections, first create the connections. In this case, data source naming becomes **mandatory**.
548
503
549
504
Suppose you have an `Album` entity stored in its own database.
550
505
@@ -576,9 +531,9 @@ const defaultOptions = {
576
531
exportclassAppModule {}
577
532
```
578
533
579
-
> warning **Notice** If you don't set the `name` for a connection, its name is set to `default`. Please note that you shouldn't have multiple connections without a name, or with the same name, otherwise they will get overridden.
534
+
> warning **Notice** If you don't set the `name` for a data source, its name is set to `default`. Please note that you shouldn't have multiple connections without a name, or with the same name, otherwise they will get overridden.
580
535
581
-
At this point, you have `User` and `Album` entities registered with their own connection. With this setup, you have to tell the `TypeOrmModule.forFeature()` method and the `@InjectRepository()` decorator which connection should be used. If you do not pass any connection name, the `default`connection is used.
536
+
At this point, you have `User` and `Album` entities registered with their own data source. With this setup, you have to tell the `TypeOrmModule.forFeature()` method and the `@InjectRepository()` decorator which data source should be used. If you do not pass any data source name, the `default`data source is used.
582
537
583
538
```typescript
584
539
@Module({
@@ -590,31 +545,31 @@ At this point, you have `User` and `Album` entities registered with their own co
590
545
exportclassAppModule {}
591
546
```
592
547
593
-
You can also inject the `Connection` or `EntityManager` for a given connection:
548
+
You can also inject the `DataSource` or `EntityManager` for a given data source:
594
549
595
550
```typescript
596
551
@Injectable()
597
552
exportclassAlbumsService {
598
553
constructor(
599
554
@InjectConnection('albumsConnection')
600
-
privateconnection:Connection,
555
+
privatedataSource:DataSource,
601
556
@InjectEntityManager('albumsConnection')
602
557
privateentityManager:EntityManager,
603
558
) {}
604
559
}
605
560
```
606
561
607
-
It's also possible to inject any `Connection` to the providers:
562
+
It's also possible to inject any `DataSource` to the providers:
608
563
609
564
```typescript
610
565
@Module({
611
566
providers: [
612
567
{
613
568
provide: AlbumsService,
614
-
useFactory: (albumsConnection:Connection) => {
569
+
useFactory: (albumsConnection:DataSource) => {
615
570
returnnewAlbumsService(albumsConnection);
616
571
},
617
-
inject: [getConnectionToken('albumsConnection')],
572
+
inject: [getDataSourceToken('albumsConnection')],
618
573
},
619
574
],
620
575
})
@@ -623,7 +578,7 @@ export class AlbumsModule {}
623
578
624
579
#### Testing
625
580
626
-
When it comes to unit testing an application, we usually want to avoid making a database connection, keeping our test suites independent and their execution process as fast as possible. But our classes might depend on repositories that are pulled from the connection instance. How do we handle that? The solution is to create mock repositories. In order to achieve that, we set up [custom providers](/fundamentals/custom-providers). Each registered repository is automatically represented by an `<EntityName>Repository` token, where `EntityName` is the name of your entity class.
581
+
When it comes to unit testing an application, we usually want to avoid making a database connection, keeping our test suites independent and their execution process as fast as possible. But our classes might depend on repositories that are pulled from the data source (connection) instance. How do we handle that? The solution is to create mock repositories. In order to achieve that, we set up [custom providers](/fundamentals/custom-providers). Each registered repository is automatically represented by an `<EntityName>Repository` token, where `EntityName` is the name of your entity class.
627
582
628
583
The `@nestjs/typeorm` package exposes the `getRepositoryToken()` function which returns a prepared token based on a given entity.
629
584
@@ -642,39 +597,6 @@ export class UsersModule {}
642
597
643
598
Now a substitute `mockRepository` will be used as the `UsersRepository`. Whenever any class asks for `UsersRepository` using an `@InjectRepository()` decorator, Nest will use the registered `mockRepository` object.
644
599
645
-
#### Custom repository
646
-
647
-
TypeORM provides a feature called **custom repositories**. Custom repositories allow you to extend a base repository class, and enrich it with several special methods. To learn more about this feature, visit [this page](https://typeorm.io/#/custom-repository). Be aware that custom repositories are outside of NestJS's Dependency Injection system, thus you can't inject any values into them.
648
-
649
-
In order to create your custom repository, use the `@EntityRepository()` decorator and extend the `Repository` class.
> info **Hint** Both `@EntityRepository()` and `Repository` are imported from the `typeorm` package.
657
-
658
-
Once the class is created, the next step is to delegate instantiation responsibility to Nest. For this, we have to pass the`AuthorRepository` class to the `TypeOrm.forFeature()` method.
You may want to pass your repository module options asynchronously instead of statically. In this case, use the `forRootAsync()` method, which provides several ways to deal with async configuration.
This construction works the same as `useClass` with one critical difference - `TypeOrmModule` will lookup imported modules to reuse an existing `ConfigService` instead of instantiating a new one.
756
678
757
-
> info **Hint** Make sure that the `name` property is defined at the same level as the `useFactory`, `useClass`, or `useValue` property. This will allow Nest to properly register the connection under the appropriate injection token.
679
+
> info **Hint** Make sure that the `name` property is defined at the same level as the `useFactory`, `useClass`, or `useValue` property. This will allow Nest to properly register the data source under the appropriate injection token.
758
680
759
-
#### Custom Connection Factory
681
+
#### Custom DataSource Factory
760
682
761
-
In conjunction with async configuration using `useFactory`, `useClass`, or `useExisting`, you can optionally specify a `connectionFactory` function which will allow you to provide your own TypeORM connection rather than allowing `TypeOrmModule` to create the connection.
683
+
In conjunction with async configuration using `useFactory`, `useClass`, or `useExisting`, you can optionally specify a `dataSourceFactory` function which will allow you to provide your own TypeORM data source rather than allowing `TypeOrmModule` to create the data source.
762
684
763
-
`connectionFactory` receives the TypeORM `ConnectionOptions` configured during async configuration using `useFactory`, `useClass`, or `useExisting` and returns a `Promise` that resolves a TypeORM `Connection`.
685
+
`dataSourceFactory` receives the TypeORM `DataSourceOptions` configured during async configuration using `useFactory`, `useClass`, or `useExisting` and returns a `Promise` that resolves a TypeORM `DataSource`.
764
686
765
687
```typescript
766
688
TypeOrmModule.forRootAsync({
767
689
imports: [ConfigModule],
768
690
inject: [ConfigService],
769
691
// Use useFactory, useClass, or useExisting
770
-
// to configure the ConnectionOptions.
692
+
// to configure the DataSourceOptions.
771
693
useFactory: (configService:ConfigService) => ({
772
694
type: 'mysql',
773
695
host: configService.get('HOST'),
774
-
port: +configService.get<number>('PORT'),
696
+
port: +configService.get('PORT'),
775
697
username: configService.get('USERNAME'),
776
698
password: configService.get('PASSWORD'),
777
699
database: configService.get('DATABASE'),
778
-
entities: [__dirname+'/**/*.entity{.ts,.js}'],
700
+
entities: [],
779
701
synchronize: true,
780
702
}),
781
-
//connectionFactory receives the configured ConnectionOptions
782
-
// and returns a Promise<Connection>.
783
-
connectionFactory: async (options) => {
784
-
constconnection=awaitcreateConnection(options);
785
-
returnconnection;
703
+
//dataSource receives the configured DataSourceOptions
0 commit comments