spelling and general improvements (part 5)

This commit is contained in:
Daniel Lang 2017-10-04 13:08:40 +02:00
parent bf18b05fae
commit bd9041f0f5
19 changed files with 305 additions and 335 deletions

View File

@ -517,14 +517,14 @@ Examples:
```typescript
@Transaction()
save(@TransactionManager() manager: EntityManager, @Body() user: User) {
save(@TransactionManager() manager: EntityManager, user: User) {
return manager.save(user);
}
```
```typescript
@Transaction()
save(@Body() user: User, @TransactionRepository(User) userRepository: Repository<User>) {
save(user: User, @TransactionRepository(User) userRepository: Repository<User>) {
return userRepository.save(user);
}
```

View File

@ -7,7 +7,7 @@
## How to create self referencing relation
Self-referencing relations are relations which have relation to themself.
Self-referencing relations are relations which have a relation to themself.
This is useful when you are storing entities in a tree-like structures.
Also "adjacency list" pattern is implemented used self-referenced relations.
For example, you want to create categories tree in your application.
@ -83,7 +83,7 @@ export class User {
}
```
When you load a user without `profile` joined you won't have in your user object any information about profile,
When you load a user without `profile` joined you won't have any information about profile in your user object,
even profile id:
```javascript
@ -91,11 +91,11 @@ User {
id: 1,
name: "Umed"
}
````
```
But sometimes you want to get known what is "profile id" of this user without loading the whole profile for this user.
To do this you just need to add another property into your entity with `@Column` decorator
named exactly as column created by your relation. Example:
But sometimes you want to know what is the "profile id" of this user without loading the whole profile for this user.
To do this you just need to add another property to your entity with `@Column`
named exactly as the column created by your relation. Example:
```typescript
import {Entity, PrimaryGeneratedColumn, Column, OneToOne, JoinColumn} from "typeorm";
@ -120,7 +120,7 @@ export class User {
}
```
That's all. Next time you load profile object it will contain a profile id:
That's all. Next time you load a user object it will contain a profile id:
```javascript
User {
@ -128,7 +128,7 @@ User {
name: "Umed",
profileId: 1
}
````
```
## How to load relations in entities
@ -151,10 +151,10 @@ const user = await connection
```
Using `QueryBuilder` you can do `innerJoinAndSelect` instead of `leftJoinAndSelect`
(to get known difference between `LEFT JOIN` and `INNER JOIN` refer to SQL documentation),
(to learn the difference between `LEFT JOIN` and `INNER JOIN` refer to your SQL documentation),
you can join relation data by a condition, make ordering, etc.
For more information how to use `QueryBuilder` refer this [documentation](select-query-builder.md).
Learn more about [`QueryBuilder`](select-query-builder.md).
## Avoid relation property initializers
@ -183,9 +183,9 @@ export class Question {
}
```
However in TypeORM entities it may cause you problems.
To understand the problem, let's first try to load Question entity WITHOUT initializer set.
When you load question it will return you object like this:
However in TypeORM entities it may cause problems.
To understand the problem, let's first try to load a Question entity WITHOUT the initializer set.
When you load a question it will return an object like this:
```javascript
Question {
@ -196,7 +196,7 @@ Question {
Now when you save this object `categories` inside it won't be touched - because it is unset.
But if you have initializer loaded object will look like as follow:
But if you have initializer, the loaded object will look like as follow:
```javascript
Question {
@ -206,11 +206,11 @@ Question {
}
```
When you save such object it will check if there any categories in the database bind to a question -
When you save the object it will check if there are any categories in the database bind to the question -
and it will detach all of them. Why? Because relation equal to `[]` or any items inside it will be considered
like something was removed from it, there is no other way to check if object was removed from entity or not.
like something was removed from it, there is no other way to check if an object was removed from entity or not.
So, this saving such object will bring you problems - it will remove all previously set categories.
Therefoe, saving an object like this will bring you problems - it will remove all previously set categories.
How to avoid this behaviour? Simply don't initialize arrays in your entities.
Same rule applies to a constructor - don't initialize it in a constructor as well.

View File

@ -12,27 +12,27 @@
## What are relations
Relations helps to work with related entities easily.
Relations helps you to work with related entities easily.
There are several types of relations:
* one-to-one using `@OneToOne` decorator
* many-to-one using `@ManyToOne` decorator
* one-to-many using `@OneToMany` decorator
* many-to-many using `@ManyToMany` decorator
* one-to-one using `@OneToOne`
* many-to-one using `@ManyToOne`
* one-to-many using `@OneToMany`
* many-to-many using `@ManyToMany`
## Relation options
There are several options you can specify in relations:
There are several options you can specify for relations:
* `eager: boolean` - If set to true then relation will always be loaded with main entity when using `find*` methods or `QueryBuilder` on this entity
* `cascadeInsert: boolean` - If set to true then related object will be inserted into database if it does not exist yet.
* `cascadeUpdate: boolean` - If set to true then related object will be updated in the database on entity save.
* `cascadeRemove: boolean` - If set to true then related object will be removed from the database on entity save and without related object.
* `cascadeAll: boolean` - Sets all `cascadeInsert`, `cascadeUpdate`, `cascadeRemove` options.
* `eager: boolean` - If set to true, the relation will always be loaded with the main entity when using `find*` methods or `QueryBuilder` on this entity
* `cascadeInsert: boolean` - If set to true, the related object will be inserted into database if it does not exist yet.
* `cascadeUpdate: boolean` - If set to true, the related object will be updated in the database on entity save.
* `cascadeRemove: boolean` - If set to true, the related object will be removed from the database on entity save and without related object.
* `cascadeAll: boolean` - Sets `cascadeInsert`, `cascadeUpdate`, `cascadeRemove` at once.
* `onDelete: "RESTRICT"|"CASCADE"|"SET NULL"` - specifies how foreign key should behave when referenced object is deleted
* `primary: boolean` - Indicates if this relation's column will be primary column.
* `nullable: boolean` - Indicates if this relation's column can be nullable or not. By default it is nullable.
Its not recommended to set it to false if you are using cascades in your relations.
* `primary: boolean` - Indicates whether this relation's column will be a primary column or not.
* `nullable: boolean` - Indicates whether this relation's column is nullable or not. By default it is nullable.
It's not recommended to set it to false if you are using cascades in your relations.
## Cascades
@ -94,37 +94,37 @@ question.categories = [category1, category2];
await connection.manager.save(question);
```
As you can see in example we did not called `save` method for `category1` and `category2` objects.
As you can see in this example we did not called `save` for `category1` and `category2`.
They will be automatically inserted, because we set `cascadeInsert` to true.
When using `cascadeUpdate` save method is called for each object in relations of your currently saving entity.
It means each entity in relation will be automatically changed if they exist in the database.
When using `cascadeUpdate` `save` is called for each object in, that is in a relation with the entity being saved.
This means, that each entity in the relation will be automatically changed if they exist in the database.
When using `cascadeRemove` remove method is called for each missing in the relation object.
Good example of this method is relation between `Question` and `Answer` entities.
When you remove `Question` which has `answers: Answer[]` relation you want to remove all answers from the database as well.
When using `cascadeRemove` `remove` is called for each object missing in the relation.
Good example of this method is the relation between `Question` and `Answer` entities.
When you remove a `Question` which has `answers: Answer[]` relation you want to remove all answers from the database as well.
Keep in mind - great power comes with great responsibility.
Cascades may seem good and easy way to work with relations,
but they also may bring bugs and security issues when some undesirable object is being saved into the database.
Also they are providing less explicit way of saving new objects into the database.
Cascades may seem a good and easy way to work with relations,
but they may also bring bugs and security issues when some undesired object is being saved into the database.
Also, they provide a less explicit way of saving new objects into the database.
## `@JoinColumn` options
`@JoinColumn` decorator not only defines which side of relation contain join column with foreign key,
`@JoinColumn` not only defines which side of the relation contains the join column with a foreign key,
but also allows to customize join column name and referenced column name.
When we set `@JoinColumn` decorator it creates column in the database automatically named `propertyName + referencedColumnName`.
When we set `@JoinColumn` it creates a column in the database automatically named `propertyName + referencedColumnName`.
For example:
```typescript
@ManyToOne(type => Category)
@JoinColumn() // this decorator is optional for ManyToOne decorator, but required for OneToOne decorator
@JoinColumn() // this decorator is optional for @ManyToOne, but required for @OneToOne
category: Category;
```
This code will create `categoryId` column in the database.
If you want to change this name in the database you can specify custom join column name:
This code will create a `categoryId` column in the database.
If you want to change this name in the database you can specify a custom join column name:
```typescript
@ManyToOne(type => Category)
@ -132,10 +132,10 @@ If you want to change this name in the database you can specify custom join colu
category: Category;
```
Join columns are always reference to some columns (using foreign key).
By default your relation always reference to primary column of related entity.
Join columns are always a reference to some columns (using a foreign key).
By default your relation always refers to the primary column of the related entity.
If you want to create relation with other columns of the related entity -
you can specify them in `@JoinColumn` decorator as well:
you can specify them in `@JoinColumn` as well:
```typescript
@ManyToOne(type => Category)
@ -143,15 +143,15 @@ you can specify them in `@JoinColumn` decorator as well:
category: Category;
```
Relation now referenced to `name` column of the `Category` entity, instead of `id`.
The relation now refers to `name` of the `Category` entity, instead of `id`.
Column name for such relation will become `categoryId`
## `@JoinTable` options
`@JoinTable` decorator is used for `many-to-many` relations and describes join columns of the "junction" table.
Junction table is a special separate table created automatically by ORM with columns referenced to related entities.
You can change column names inside junction tables and their referenced columns as easy as with `@JoinColumn` decorator:
Also you can change name of the generated "junction" table.
`@JoinTable` is used for `many-to-many` relations and describes join columns of the "junction" table.
A junction table is a special separate table created automatically by TypeORM with columns that refer to the related entities.
You can change column names inside junction tables and their referenced columns with `@JoinColumn`:
You can also change the ame of the generated "junction" table.
```typescript
@ManyToMany(type => Category)
@ -170,4 +170,4 @@ categories: Category[];
```
If destination table has composite primary keys,
then array of properties must be send to `@JoinTable` decorator.
then array of properties must be send to `@JoinTable`.

View File

@ -6,27 +6,27 @@
## `Repository` API
* `manager` - Gets `EntityManager` used by this repository.
* `manager` - The `EntityManager` used by this repository.
```typescript
const manager = repository.manager;
```
* `metadata` - Gets `EntityMetadata` of the entity managed by this repository.
Learn more about transactions in [Entity Metadata](./entity-metadata.md) documentation.
* `metadata` - The `EntityMetadata` of the entity managed by this repository.
Learn more about [transactions in Entity Metadata](./entity-metadata.md).
```typescript
const metadata = repository.metadata;
```
* `queryRunner` - Gets query runner used by `EntityManager`.
* `queryRunner` - The query runner used by `EntityManager`.
Used only in transactional instances of EntityManager.
```typescript
const queryRunner = repository.queryRunner;
```
* `target` - Gets target class of the entity managed by this repository.
* `target` - The target entity class managed by this repository.
Used only in transactional instances of EntityManager.
```typescript
@ -34,7 +34,7 @@ const target = repository.target;
```
* `createQueryBuilder` - Creates a query builder use to build SQL queries.
Learn more about query builder in [QueryBuilder](select-query-builder.md) documentation.
Learn more about [QueryBuilder](select-query-builder.md).
```typescript
const users = await repository
@ -43,7 +43,7 @@ const users = await repository
.getMany();
```
* `hasId` - Checks if given entity's has its primary column property values are defined.
* `hasId` - Checks if the given entity's primary column property is defined.
```typescript
if (repository.hasId(user)) {
@ -51,14 +51,14 @@ const users = await repository
}
```
* `getId` - Gets given entity's primary column property values.
If entity has composite primary keys then returned value will be an object with names and values of primary columns.
* `getId` - Gets the primary column property values of the given entity.
If entity has composite primary keys then the returned value will be an object with names and values of primary columns.
```typescript
const userId = repository.getId(user); // userId === 1
```
* `create` - Creates a new instance of `User` object. Optionally accepts an object literal with user properties
* `create` - Creates a new instance of `User`. Optionally accepts an object literal with user properties
which will be written into newly created user object
```typescript
@ -77,9 +77,9 @@ const user = new User();
repository.merge(user, { firstName: "Timber" }, { lastName: "Saw" }); // same as user.firstName = "Timber"; user.lastName = "Saw";
```
* `preload` - Creates a new entity from the given plan javascript object. If entity already exist in the database, then
* `preload` - Creates a new entity from the given plain javascript object. If the entity already exist in the database, then
it loads it (and everything related to it), replaces all values with the new ones from the given object
and returns this new entity. This new entity is actually a loaded from the db entity with all properties
and returns the new entity. The new entity is actually an entity loaded from the db with all properties
replaced from the new object.
```typescript
@ -96,9 +96,9 @@ const user = await repository.preload(partialUser);
```
* `save` - Saves a given entity or array of entities.
If entity already exist in the database then it updates it.
If entity does not exist in the database yet it inserts it.
It saves all given entities in a single transaction (in the case if entity manager is not transactional).
If the entity already exist in the database, it is updated.
If the entity does not exist in the database, it is inserted.
It saves all given entities in a single transaction (in the case of entity manager is not transactional).
Also supports partial updating since all undefined properties are skipped.
```typescript
@ -125,7 +125,7 @@ await repository.updateById(1, { firstName: "Rizzrak" });
```
* `remove` - Removes a given entity or array of entities.
It removes all given entities in a single transaction (in the case if entity manager is not transactional).
It removes all given entities in a single transaction (in the case of entity manager is not transactional).
```typescript
await repository.remove(user);
@ -163,7 +163,7 @@ const timbers = await repository.find({ firstName: "Timber" });
* `findAndCount` - Finds entities that match given find options.
Also counts all entities that match given conditions,
but ignores pagination settings (from and take options).
but ignores pagination settings (`from` and `take` options).
```typescript
const [timbers, timbersCount] = await repository.findAndCount({ firstName: "Timber" });
@ -201,7 +201,7 @@ await repository.clear();
## `TreeRepository` API
* `findTrees` - Gets complete trees for all roots in the table.
* `findTrees` - Gets complete tree for all roots in the table.
```typescript
const treeCategories = await repository.findTrees();
@ -268,7 +268,7 @@ const parents = await repository
.getMany();
```
* `countAncestors` - Gets number of ancestors of the entity.
* `countAncestors` - Gets the number of ancestors of the entity.
```typescript
const parentsCount = await repository.countAncestors(childCategory);
@ -276,4 +276,4 @@ const parentsCount = await repository.countAncestors(childCategory);
## `MongoRepository` API
For `MongoRepository` API refer [this documentation](./mongodb.md).
For `MongoRepository` API refer to [the MongoDB documentation](./mongodb.md).

View File

@ -1,6 +1,6 @@
# Roadmap
See what amazing new features we are expecting to land in next TypeORM versions.
See what amazing new features we are expecting to land in the next TypeORM versions.
## Note on 1.0.0 release

View File

@ -1,9 +1,9 @@
# Defining entity schemas in json files
You can define entity and its columns right on the model, using decorators.
But some people prefer to defined entity and its columns inside separate files
which are called in TypeORM "entity schemas".
In TypeORM you can define entity schemas in `js`, `json` files.
You can define an entity and its columns right in the model, using decorators.
But some people prefer to define an entity and its columns inside separate files
which are called "entity schemas" in TypeORM.
In TypeORM you can define entity schemas as `js` or `json` files.
TBD.

View File

@ -3,8 +3,7 @@
* [What is `QueryBuilder`](#what-is-querybuilder)
* [How to create and use a `QueryBuilder`](#how-to-create-and-use-a-querybuilder)
* [Building `SELECT` queries](#building-select-queries)
* [Getting values using `QueryBuilder`](#getting-values-using-querybuilder)
* [What are aliases stand for?](#what-are-aliases-stand-for?)
* [What are aliases for?](#what-are-aliases-for?)
* [Using parameters to escape data](#using-parameters-to-escape-data)
* [Adding `WHERE` expression](#adding-where-expression)
* [Adding `HAVING` expression](#adding-having-expression)
@ -17,7 +16,7 @@
* [Join without selection](#join-without-selection)
* [Joining any entity or table](#joining-any-entity-or-table)
* [Joining and mapping functionality](#joining-and-mapping-functionality)
* [Getting result query](#getting-result-query)
* [Getting the generated query](#getting-the-generated-query)
* [Getting raw results](#getting-raw-results)
* [Streaming result data](#streaming-result-data)
* [Using pagination](#using-pagination)
@ -28,9 +27,9 @@
## What is `QueryBuilder`
`QueryBuilder` one of the most power TypeORM feature -
it allows you to build SQL query using elegant and convenient syntax,
execute it and get automatically transformed entities.
`QueryBuilder` is one of the most powerful features of TypeORM -
it allows you to build SQL queries using elegant and convenient syntax,
execute them and get automatically transformed entities.
Simple example of `QueryBuilder`:
@ -42,7 +41,7 @@ const firstUser = await connection
.getOne();
```
It builds following SQL query:
It builds the following SQL query:
```sql
SELECT
@ -65,7 +64,7 @@ User {
## How to create and use a `QueryBuilder`
There are several ways how you can create query builder:
There are several ways how you can create a `Query Builder`:
* Using connection:
@ -102,7 +101,7 @@ There are several ways how you can create query builder:
.getOne();
```
There are 5 types of `QueryBuilder` available:
There are 5 diffrent `QueryBuilder`s available:
* `SelectQueryBuilder` used to build and execute `SELECT` queries. Example:
@ -163,12 +162,10 @@ There are 5 types of `QueryBuilder` available:
You can switch between different types of query builder within any of them,
once you do it - you will get a new instance of query builder (unlike all other methods).
## Building `SELECT` queries
## Getting values using `QueryBuilder`
To get a single result from the database,
for example to get user by id or name you must use `getOne` method:
for example to get a user by id or name you must use `getOne`:
```typescript
const timber = await getRepository(User)
@ -177,8 +174,8 @@ const timber = await getRepository(User)
.getOne();
```
To get a multiple results from the database,
for example to get all users from the database use `getMany` method:
To get multiple results from the database,
for example to get all users from the database use `getMany`:
```typescript
const users = await getRepository(User)
@ -187,11 +184,11 @@ const users = await getRepository(User)
```
There are two types of results you can get using select query builder: **entities** or **raw results**.
Most of times you need to select real entities from your database, for example users.
For this purpose you use `getOne` and `getMany` methods.
But sometimes you need to select some specific data, let's say *sum of all user photos*.
Such data is not entity, its called raw data.
To get raw data you use `getRawOne` and `getRawMany` methods.
Most of the times you need to select real entities from your database, for example users.
For this purpose you use `getOne` and `getMany`.
But sometimes you need to select some specific data, let's say the *sum of all user photos*.
This data is not an entity, its called raw data.
To get raw data you use `getRawOne` and `getRawMany`.
Examples:
```typescript
@ -213,13 +210,13 @@ const photosSums = await getRepository(User)
// result will be like this: [{ id: 1, sum: 25 }, { id: 2, sum: 13 }, ...]
```
## What are aliases stand for?
## What are aliases for?
We used `createQueryBuilder("user")` everywhere. But what is "user" there?
Answer is: its just a regular SQL alias.
We use that alias everywhere in expressions where we work with selected data.
We used `createQueryBuilder("user")`. But what is "user"?
It's just a regular SQL alias.
We use aliases everywhere in except when we work with selected data.
`createQueryBuilder("user")` is equivalent for:
`createQueryBuilder("user")` is equivalent to:
```typescript
createQueryBuilder()
@ -233,8 +230,8 @@ Which will result into following sql query:
SELECT ... FROM users user
```
In this SQL query `users` is a table name and `user` is an alias we assign to this table.
Later we use this alias to access to this table:
In this SQL query `users` is the table name and `user` is an alias we assign to this table.
Later we use this alias to access the table:
```typescript
createQueryBuilder()
@ -249,23 +246,22 @@ Which produce following SQL query:
SELECT ... FROM users user WHERE user.name = 'Timber'
```
See, we access users table using `user` alias we assigned when we created a query builder.
See, we used the users table using the `user` alias we assigned when we created a query builder.
One query builder is not limited to one alias.
There are multiple aliases.
Each your select can have its own alias,
you can select from multiple tables each with own alias,
One query builder is not limited to one alias, they can have are multiple aliases.
Each select can have its own alias,
you can select from multiple tables each with its own alias,
you can join multiple tables each with its own alias.
You use those aliases to access tables are you selecting (or data you are selecting).
You can use those aliases to access tables are you selecting (or data you are selecting).
## Using parameters to escape data
We used `where("user.name = :name", { name: "Timber" })` syntax everywhere.
What `{ name: "Timber" }` stands for? Answer: its a parameter we used to prevent SQL injection.
We could do simply: `where("user.name = '" + name + "')`,
however this is not safe way and SQL injection can be easily executed there.
Safe way is to use special syntax: `where("user.name = :name", { name: "Timber" })`,
where `:name` is a parameter name. Parameter's value is specified in object: `{ name: "Timber" }`.
We used `where("user.name = :name", { name: "Timber" })`.
What does `{ name: "Timber" }` stands for? It's a parameter we used to prevent SQL injection.
We could have written: `where("user.name = '" + name + "')`,
however this is not safe as it opens the code to SQL injections.
The safe way is to use this special syntax: `where("user.name = :name", { name: "Timber" })`,
where `:name` is a parameter name and the value is specified in an object: `{ name: "Timber" }`.
```typescript
.where("user.name = :name", { name: "Timber" })
@ -280,20 +276,20 @@ is a shortcut for:
## Adding `WHERE` expression
Adding SQL `WHERE` expression is easy as:
Adding a `WHERE` expression is as easy as:
```typescript
createQueryBuilder("user")
.where("user.name = :name", { name: "Timber" })
```
Will produce following SQL query:
Will produce:
```sql
SELECT ... FROM users user WHERE user.name = 'Timber'
```
You can add `AND` into exist `WHERE` expression this way:
You can add `AND` into an exist `WHERE` expression:
```typescript
createQueryBuilder("user")
@ -301,13 +297,13 @@ createQueryBuilder("user")
.andWhere("user.lastName = :lastName", { lastName: "Saw" });
```
Will produce following SQL query:
Will produce the following SQL query:
```sql
SELECT ... FROM users user WHERE user.firstName = 'Timber' AND user.lastName = 'Saw'
```
You can add `OR` into exist `WHERE` expression this way:
You can add `OR` into an exist `WHERE` expression:
```typescript
createQueryBuilder("user")
@ -315,22 +311,22 @@ createQueryBuilder("user")
.orWhere("user.lastName = :lastName", { lastName: "Saw" });
```
Will produce following SQL query:
Will produce the following SQL query:
```sql
SELECT ... FROM users user WHERE user.firstName = 'Timber' OR user.lastName = 'Saw'
```
You can combine as many `AND` and `OR` expressions as you need.
If you use `.where` method you'll override all previous set `WHERE` expressions.
If you use `.where` more than once you'll override all previous `WHERE` expressions.
Note: be careful with `orWhere` method - if you use complex expressions with both `AND` and `OR` expressions
Note: be careful with `orWhere` - if you use complex expressions with both `AND` and `OR` expressions
keep in mind that they are stacked without any pretences.
Sometimes you'll need to create a where string instead and avoid using `orWhere` method.
Sometimes you'll need to create a where string instead and avoid using `orWhere`.
## Adding `HAVING` expression
Adding SQL `HAVING` expression is easy as:
Adding a `HAVING` expression is easy as:
```typescript
createQueryBuilder("user")
@ -343,7 +339,7 @@ Will produce following SQL query:
SELECT ... FROM users user HAVING user.name = 'Timber'
```
You can add `AND` into exist `HAVING` expression this way:
You can add `AND` into an exist `HAVING` expression:
```typescript
createQueryBuilder("user")
@ -351,13 +347,13 @@ createQueryBuilder("user")
.andHaving("user.lastName = :lastName", { lastName: "Saw" });
```
Will produce following SQL query:
Will produce the following SQL query:
```sql
SELECT ... FROM users user HAVING user.firstName = 'Timber' AND user.lastName = 'Saw'
```
You can add `OR` into exist `HAVING` expression this way:
You can add `OR` into a exist `HAVING` expression:
```typescript
createQueryBuilder("user")
@ -365,31 +361,31 @@ createQueryBuilder("user")
.orHaving("user.lastName = :lastName", { lastName: "Saw" });
```
Will produce following SQL query:
Will produce the following SQL query:
```sql
SELECT ... FROM users user HAVING user.firstName = 'Timber' OR user.lastName = 'Saw'
```
You can combine as many `AND` and `OR` expressions as you need.
If you use `.having` method you'll override all previous set `HAVING` expressions.
If you use `.having` more than once you'll override all previous `HAVING` expressions.
## Adding `ORDER BY` expression
Adding SQL `ORDER BY` expression is easy as:
Adding a `ORDER BY` expression is easy as:
```typescript
createQueryBuilder("user")
.orderBy("user.id")
```
Will produce following SQL query:
Will produce:
```sql
SELECT ... FROM users user ORDER BY user.id
```
To change order direction from ascendant to descendant (or versa) use following syntax:
You can change the order direction from ascendant to descendant (or versa):
```typescript
createQueryBuilder("user")
@ -407,7 +403,7 @@ createQueryBuilder("user")
.addOrderBy("user.id");
```
Also you can set a map of order-by fields:
You can also usea map of order-by fields:
```typescript
createQueryBuilder("user")
@ -417,23 +413,23 @@ createQueryBuilder("user")
});
```
If you use `.orderBy` method you'll override all previous set `ORDER BY` expressions.
If you use `.orderBy` more than once you'll override all previous `ORDER BY` expressions.
## Adding `LIMIT` expression
## Adding `GROUP BY` expression
Adding SQL `GROUP BY` expression is easy as:
Adding a `GROUP BY` expression is easy as:
```typescript
createQueryBuilder("user")
.groupBy("user.id")
```
Will produce following SQL query:
This Will produce the following SQL query:
```sql
SELECT ... FROM users user GROUP BY user.id
```
To add more group-by criteria use `addGroupBy` method:
To add more group-by criteria use `addGroupBy`:
```typescript
createQueryBuilder("user")
@ -441,36 +437,26 @@ createQueryBuilder("user")
.addGroupBy("user.id");
```
Also you can set a map of order-by fields:
```typescript
createQueryBuilder("user")
.orderBy({
"user.name": "ASC",
"user.id": "DESC"
});
```
If you use `.orderBy` method you'll override all previous set `ORDER BY` expressions.
If you use `.groupBy` more than once you'll override all previous `ORDER BY` expressions.
## Adding `LIMIT` expression
Adding SQL `LIMIT` expression is easy as:
Adding a `LIMIT` expression is easy as:
```typescript
createQueryBuilder("user")
.limit(10)
```
Will produce following SQL query:
Which will produce the following SQL query:
```sql
SELECT ... FROM users user LIMIT 10
```
Result SQL query depend of database type.
The resulting SQL query depends of database type.
Note LIMIT may not work as you may expect if you are using complex queries with joins or subqueries.
If you are using pagination its recommended to use `take` method instead.
If you are using pagination its recommended to use `take` instead.
## Adding `OFFSET` expression
@ -481,19 +467,19 @@ createQueryBuilder("user")
.offset(10)
```
Will produce following SQL query:
Will produce the following SQL query:
```sql
SELECT ... FROM users user OFFSET 10
```
Result SQL query depend of database type.
The resulting SQL query depends of database type.
Note OFFSET may not work as you may expect if you are using complex queries with joins or subqueries.
If you are using pagination its recommended to use `skip` method instead.
If you are using pagination its recommended to use `skip` instead.
## Joining relations
Let's say you have following entities:
Let's say you have the following entities:
```typescript
import {Entity, PrimaryGeneratedColumn, Column, OneToMany} from "typeorm";
@ -531,8 +517,7 @@ export class Photo {
}
```
Now let's say you want to load user "Timber" with all his photos.
To do it you need to use following syntax:
Now let's say you want to load user "Timber" with all his photos:
```typescript
const user = await createQueryBuilder("user")
@ -557,9 +542,8 @@ You'll get following result:
}
```
As you can see `leftJoinAndSelect` automatically loaded all timber's photos.
First method argument is relation you want to load.
Second method argument is an alias you assign to this relation's data.
As you can see `leftJoinAndSelect` automatically loaded all of timber's photos.
The first argument is the relation you want to load and the second argument is an alias you assign to this relation's table.
You can use this alias anywhere in query builder.
For example, lets take all timber's photos which aren't removed.
@ -576,10 +560,10 @@ This will generate following sql query:
```sql
SELECT user.*, photo.* FROM users user
LEFT JOIN photos photo ON photo.user = user.id
WHERE user.name = 'Timber' AND photo.isRemoved = TRUE
WHERE user.name = 'Timber' AND photo.isRemoved = FALSE
```
You can also add condition to join expression instead of using "where":
You can also add conditions to the join expression instead of using "where":
```typescript
const user = await createQueryBuilder("user")
@ -592,13 +576,13 @@ This will generate following sql query:
```sql
SELECT user.*, photo.* FROM users user
LEFT JOIN photos photo ON photo.user = user.id AND photo.isRemoved = TRUE
LEFT JOIN photos photo ON photo.user = user.id AND photo.isRemoved = FALSE
WHERE user.name = 'Timber'
```
## Inner and left joins
If you want to use `INNER JOIN` instead of `JEFT JOIN` just use `innerJoinAndSelect` method instead:
If you want to use `INNER JOIN` instead of `JEFT JOIN` just use `innerJoinAndSelect` instead:
```typescript
const user = await createQueryBuilder("user")
@ -607,22 +591,22 @@ const user = await createQueryBuilder("user")
.getOne();
```
This will generate following sql query:
This will generate:
```sql
SELECT user.*, photo.* FROM users user
INNER JOIN photos photo ON photo.user = user.id AND photo.isRemoved = TRUE
INNER JOIN photos photo ON photo.user = user.id AND photo.isRemoved = FALSE
WHERE user.name = 'Timber'
```
Difference between `LEFT JOIN` and `INNER JOIN` is that `INNER JOIN` won't return you timber if he does not have any photos.
`LEFT JOIN` will return you timber even if he don't have photos.
To learn more about different join types refer to SQL documentation.
Difference between `LEFT JOIN` and `INNER JOIN` is that `INNER JOIN` won't return a user if it does not have any photos.
`LEFT JOIN` will return you the user even if it doesn't have photos.
To learn more about different join types refer to the SQL documentation.
## Join without selection
You can join data without its selection.
To do that use `leftJoin` or `innerJoin` methods. Example:
To do that use `leftJoin` or `innerJoin`:
```typescript
const user = await createQueryBuilder("user")
@ -631,7 +615,7 @@ const user = await createQueryBuilder("user")
.getOne();
```
This will generate following sql query:
This will generate:
```sql
SELECT user.* FROM users user
@ -639,11 +623,11 @@ SELECT user.* FROM users user
WHERE user.name = 'Timber'
```
This will select timber only he has photos, but won't return his photos in result.
This will select timber if he has photos, but won't return his photos.
## Joining any entity or table
You can join not only relations, but also other not related entities or tables.
You can not only join relations, but also other not related entities or tables.
Examples:
```typescript
@ -660,7 +644,7 @@ const user = await createQueryBuilder("user")
## Joining and mapping functionality
Add `profilePhoto` property to `User` entity and you can map any data into that property using `QueryBuilder`:
Add `profilePhoto` to `User` entity and you can map any data into that property using `QueryBuilder`:
```typescript
export class User {
@ -677,14 +661,14 @@ const user = await createQueryBuilder("user")
.getOne();
```
This will load timber's profile photo and set it to `user.profilePhoto` property.
If you want to load and map a single entity use `leftJoinAndMapOne` method.
If you want to load and map a multiple entities use `leftJoinAndMapMany` method.
This will load timber's profile photo and set it to `user.profilePhoto`.
If you want to load and map a single entity use `leftJoinAndMapOne`.
If you want to load and map multiple entities use `leftJoinAndMapMany`.
## Getting result query
## Getting the generated query
Sometimes you may want to get a SQL query `QueryBuilder` generates for you.
To do it use `getSql` method:
Sometimes you may want to get the SQL query generated by `QueryBuilder`.
To do it use `getSql`:
```typescript
const sql = createQueryBuilder("user")
@ -693,7 +677,7 @@ const sql = createQueryBuilder("user")
.getSql();
```
For debugging purposes you can use `printSql` method:
For debugging purposes you can use `printSql`:
```typescript
const users = await createQueryBuilder("user")
@ -703,16 +687,16 @@ const users = await createQueryBuilder("user")
.getMany();
```
This query will return you users and print in the console sql it used to get those users.
This query will return users and print the used sql statement to the console.
## Getting raw results
There are two types of results you can get using select query builder: **entities** and **raw results**.
Most of times you need to select real entities from your database, for example users.
For this purpose you use `getOne` and `getMany` methods.
But sometimes you need to select some specific data, let's say *sum of all user photos*.
Such data is not entity, its called raw data.
To get raw data you use `getRawOne` and `getRawMany` methods.
For this purpose you use `getOne` and `getMany`.
But sometimes you need to select specific data, let's say the *sum of all user photos*.
Such data is not a entity, its called raw data.
To get raw data you use `getRawOne` and `getRawMany`.
Examples:
```typescript
@ -736,8 +720,8 @@ const photosSums = await getRepository(User)
## Streaming result data
You can use `stream` method which returns you stream.
Streaming returns you raw data, you must handle entities transformation manually:
You can use `stream` which returns you stream.
Streaming returns you raw data and you must handle entities transformation manually:
```typescript
const stream = await getRepository(User)
@ -748,8 +732,8 @@ const stream = await getRepository(User)
## Using pagination
Most of times developing applications you need a pagination functionality.
This is used if you have pagination, page slider, infinite scroll components in your application.
Most of the times when you develope an application you need pagination functionality.
This is used if you have pagination, page slider or infinite scroll components in your application.
```typescript
const users = await getRepository(User)
@ -759,7 +743,7 @@ const users = await getRepository(User)
.getMany();
```
This will give you first 10 users with their photos.
This will give you the first 10 users with their photos.
```typescript
const users = await getRepository(User)
@ -781,12 +765,12 @@ const users = await getRepository(User)
.getMany();
```
This will skip first 5 users and take 10 users after them.
This will skip the first 5 users and take 10 users after them.
`take` and `skip` may look like we are using `limit` and `offset`, but its actually not.
`limit` and `offset` may not work as you expect once you'll have more complicated queries with joins or subqueries.
Using `take` and `skip` methods will prevent those issues.
`take` and `skip` may look like we are using `limit` and `offset`, but they don't.
`limit` and `offset` may not work as you expect once you have more complicated queries with joins or subqueries.
Using `take` and `skip` will prevent those issues.
## Set locking
@ -822,7 +806,7 @@ Optimistic locking works in conjunction with `@Version` and `@UpdatedDate` decor
## Partial selection
If you want to select only some entity properties you can use following syntax:
If you want to select only some entity properties you can use the following syntax:
````typescript
const users = await getRepository(User)
@ -834,13 +818,12 @@ const users = await getRepository(User)
.getMany();
````
This will select only `id` and `name` properties of `User` entity.
This will only select `id` and `name` of `User`.
## Using subqueries
You can easily create subqueries. Subqueries are supported in `FROM`, `WHERE` and `JOIN` expressions.
Example how to use subquery in where expression:
Example:
```typescript
const qb = await getRepository(Post).createQueryBuilder("post");
@ -850,7 +833,7 @@ const posts = qb
.getMany();
```
More elegant way to do same is:
More elegant way to do the same:
```typescript
const posts = await connection.getRepository(Post)
@ -867,7 +850,7 @@ const posts = await connection.getRepository(Post)
.getMany();
```
Alternative, you can create a separate query builder and use its generated SQL:
Alternatively, you can create a separate query builder and use its generated SQL:
```typescript
const userQb = await connection.getRepository(User)
@ -882,7 +865,7 @@ const posts = await connection.getRepository(Post)
.getMany();
```
You can do subquery in `FROM` expression this way:
You can create subqueries in `FROM` like this:
```typescript
const userQb = await connection.getRepository(User)
@ -898,7 +881,7 @@ const posts = await connection
.getRawMany();
```
or using more elegant syntax:
or using more a elegant syntax:
```typescript
const posts = await connection
@ -913,9 +896,9 @@ const posts = await connection
.getRawMany();
```
If you want to add subselect as "second from" use `addFrom` method.
If you want to add a subselect as a "second from" use `addFrom`.
You can use subselects in `SELECT` statements as well:
You can use subselects in a `SELECT` statements as well:
```typescript
const posts = await connection

View File

@ -8,7 +8,7 @@
## Setting up a connection
In sequelize you create connection this way:
In sequelize you create a connection this way:
```javascript
const sequelize = new Sequelize("database", "username", "password", {
@ -26,7 +26,7 @@ sequelize
});
```
In TypeORM you create connection following way:
In TypeORM you create a connection like this:
```typescript
import {createConnection} from "typeorm";
@ -44,7 +44,7 @@ createConnection({
});
```
Then you can get your connection instance from anywhere in your app using `getConnection` function.
Then you can get your connection instance from anywhere in your app using `getConnection`.
## Schema synchronization
@ -69,7 +69,7 @@ createConnection({
## Creating a models
This is how define models in sequelize:
This is how models are defined in sequelize:
```javascript
module.exports = function(sequelize, DataTypes) {
@ -97,7 +97,7 @@ module.exports = function(sequelize, DataTypes) {
};
```
In TypeORM such models are called entities and you can define them this way:
In TypeORM these models are called entities and you can define them like this:
```typescript
import {Entity, PrimaryGeneratedColumn, Column} from "typeorm";
@ -142,17 +142,17 @@ Its highly recommended to define one entity class per file.
TypeORM allows you to use your classes as database models
and provides you a declarative way to define what part of your model
will become part of your database table.
Power of TypeScript gives you type hinting and other useful features that you can use in classes.
The power of TypeScript gives you type hinting and other useful features that you can use in classes.
## Other model settings
Following in sequelize:
The following in sequelize:
```javascript
flag: { type: Sequelize.BOOLEAN, allowNull: true, defaultValue: true },
```
Can be achieved this way in TypeORM:
Can be achieved in TypeORM like this:
```typescript
@Column({ nullable: true, default: true })
@ -165,7 +165,7 @@ Following in sequelize:
flag: { type: Sequelize.BOOLEAN, defaultValue: true },
```
Can be achieved this way in TypeORM:
Is written like this in TypeORM:
```typescript
@Column({ default: () => "NOW()" })
@ -191,7 +191,7 @@ Following in sequelize:
fieldWithUnderscores: { type: Sequelize.STRING, field: 'field_with_underscores' },
```
Can be achieved this way in TypeORM:
Translates to this in TypeORM:
```typescript
@Column({ name: "field_with_underscores" })
@ -225,7 +225,7 @@ Can be achieved this way in TypeORM:
identifier: string;
```
To create `createDate` and `updateDate`-like columns you need to defined two columns (named it as you want) in your entity:
To create `createDate` and `updateDate`-like columns you need to defined two columns (name it what you want) in your entity:
```typescript
@CreateDateColumn();
@ -237,7 +237,7 @@ updateDate: Date;
### Working with models
To create a new model in sequelize you do following:
To create a new model in sequelize you write:
```javascript
const employee = await Employee.create({ name: "John Doe", title: "senior engineer" });
@ -257,7 +257,7 @@ or
const employee = Employee.create({ name: "John Doe", title: "senior engineer" });
```
if you want to load exist entity from the database and replace some of its properties you can use following method:
if you want to load an exist entity from the database and replace some of its properties you can use following method:
```typescript
const employee = await Employee.preload({ id: 1, name: "John Doe" });
@ -275,7 +275,7 @@ In TypeORM you simply do:
console.log(employee.name);
```
To create index in sequelize you do following:
To create an index in sequelize you do:
```typescript
sequelize.define("user", {}, {

View File

@ -10,10 +10,10 @@ If you have a question you can ask it on [StackOverflow](https://stackoverflow.c
### Want a community support?
If you want a community support or simply want to chat with friendly TypeORM lovers and users you can do it in [gitter](https://gitter.im/typeorm/typeorm).
If you want a community support or simply want to chat with friendly TypeORM enthusiasts and users you can do it in [gitter](https://gitter.im/typeorm/typeorm).
### Want a professional commercial support?
TypeORM core team always ready to provide a professional commercial support.
The TypeORM core team is always ready to provide professional commercial support.
We are ready to work with any team in any part of the world.
Please contact us via [email](mailto:support@typeorm.io).
[Please contact us](mailto:support@typeorm.io).

View File

@ -49,7 +49,7 @@ createConnection({
**Don't forget to include reflect-metadata**
Don't forget to include reflect-metadata package in html:
Don't forget to include reflect-metadata in your html:
```html
<script src="./node_modules/reflect-metadata/Reflect.js"></script>
@ -57,7 +57,7 @@ Don't forget to include reflect-metadata package in html:
## Cordova / PhoneGap / Ionic apps
TypeORM is able to run on Cordova, PhoneGap, Ionic apps using
TypeORM is able to run on Cordova, PhoneGap, Ionic apps using the
[cordova-sqlite-storage](https://github.com/litehelpers/Cordova-sqlite-storage) plugin
You have the option to choose between module loaders just like in browser package.
For an example how to use TypeORM in Cordova see [typeorm/cordova-example](https://github.com/typeorm/cordova-example) and for Ionic see [typeorm/ionic-example](https://github.com/typeorm/ionic-example).

View File

@ -6,7 +6,7 @@
## Creating and using transactions
Transactions are creating using `Connection` or `EntityManager` objects.
Transactions are creating using `Connection` or `EntityManager`.
Examples:
```typescript
@ -27,7 +27,7 @@ await getManager().transaction(transactionalEntityManager => {
});
```
Everything you want to run in a transaction must be executed in a callback provided to a transaction:
Everything you want to run in a transaction must be executed in a callback:
```typescript
import {getManager} from "typeorm";
@ -39,56 +39,43 @@ await getManager().transaction(async transactionalEntityManager => {
});
```
The most important restriction of using transaction is to **ALWAYS** use provided instance of entity manager -
The most important restriction when working in an transaction is, to **ALWAYS** use the provided instance of entity manager -
`transactionalEntityManager` in this example.
If you'll use global manager (from `getManager` or manager from connection) you'll have problems.
You also cannot use classes which use global manager or connection to execute their queries.
All operations **MUST** be executed using provided transactional entity manager.
All operations **MUST** be executed using the provided transactional entity manager.
## Transaction decorators
There are few decorators which can help you organize your transactions -
There are a few decorators which can help you organize your transactions -
`@Transaction`, `@TransactionManager` and `@TransactionRepository`.
`@Transaction` wraps all its execution into a single database transaction,
and `@TransactionManager` provides transaction entity manager which must be used to execute queries inside this transaction.
Example how you can apply transactional decorators in your controllers:
and `@TransactionManager` provides a transaction entity manager which must be used to execute queries inside this transaction:
```typescript
@Controller()
export class UserController {
@Transaction()
@Post("/users")
save(@TransactionManager() manager: EntityManager, @Body() user: User) {
return manager.save(user);
}
@Transaction()
save(@TransactionManager() manager: EntityManager, user: User) {
return manager.save(user);
}
```
You **must** always use provided by `@TransactionManager` decorator manager here as well.
You **must** always use the manager provided by `@TransactionManager`.
However, you can also inject transaction repository (which use transaction entity manager under the hood),
using `@TransactionRepository` decorator:
However, you can also inject transaction repository (which uses transaction entity manager under the hood),
using `@TransactionRepository`:
```typescript
@Controller()
export class UserController {
@Transaction()
@Post("/users")
save(@Body() user: User, @TransactionRepository(User) userRepository: Repository<User>) {
return userRepository.save(user);
}
@Transaction()
save(user: User, @TransactionRepository(User) userRepository: Repository<User>) {
return userRepository.save(user);
}
```
You can inject both built-in TypeORM's repositories like `Repository`, `TreeRepository` and `MongoRepository`
(using `@TransactionRepository(Entity) entityRepository: Repository<Entity>` like syntax)
or custom repositories (classes extending built-in TypeORM's repositories classes and decorated with `@EntityRepository` decorator)
using the `@TransactionRepository() customRepository: CustomRepository` syntax.
(using `@TransactionRepository(Entity) entityRepository: Repository<Entity>`)
or custom repositories (classes extending the built-in TypeORM's repositories classes and decorated with `@EntityRepository`)
using the `@TransactionRepository() customRepository: CustomRepository`.
## Using `QueryRunner` to create and control state of single database connection
@ -138,8 +125,8 @@ try {
There are 3 methods to control transactions in `QueryRunner`:
* `startTransaction` - starts a new transaction inside this query runner instance
* `commitTransaction` - commits all changes made using this query runner instance
* `rollbackTransaction` - rollbacks all changes made using this query runner instance
* `startTransaction` - starts a new transaction inside the query runner instance
* `commitTransaction` - commits all changes made using the query runner instance
* `rollbackTransaction` - rolls all changes made using the query runner instance back
More information about query runners see [here](./query-runner.md).
Learn more about [Query Runner](./query-runner.md).

View File

@ -1,6 +1,6 @@
# Tree Entities
TypeORM supports Adjacency list and Closure table patterns of storing tree structures.
TypeORM supports the Adjacency list and Closure table patterns for storing tree structures.
* [Adjacency list](#adjacency-list)
* [Closure table](#closure-table)
@ -8,8 +8,8 @@ TypeORM supports Adjacency list and Closure table patterns of storing tree struc
### Adjacency list
Adjacency list is a simple model with self-referencing.
Benefit of this approach is simplicity,
drawback is you can't load big tree in once because of joins limitation.
The benefit of this approach is simplicity,
drawback is that you can't load big tree in once because of join limitations.
Example:
```typescript

View File

@ -14,4 +14,4 @@ await getConnection()
.execute();
```
This is the most efficient in terms of performance way to update things in your database.
This is the most efficient way in terms of performance to update entities in your database.

View File

@ -1,7 +1,7 @@
# Using with JavaScript
TypeORM can be used not only with TypeScript, but also with JavaScript.
Everything is the same, except you need to omit types and if your platform does not support ES6 classes then you need to define an objects with all required metadata.
Everything is the same, except you need to omit types and if your platform does not support ES6 classes then you need to define objects with all required metadata.
##### app.js
@ -102,4 +102,4 @@ module.exports = {
};
```
Learn more about how to use TypeORM with JavaScript from [this repository](https://github.com/typeorm/javascript-example).
You can checkout this example [typeorm/javascript-example](https://github.com/typeorm/javascript-example) to learn more.

View File

@ -16,7 +16,7 @@
## Initialize a new TypeORM project
You can create a new project with everything already setup using following command:
You can create a new project with everything already setup:
```
typeorm init
@ -34,16 +34,16 @@ It creates all files needed for a basic project with TypeORM:
Then you can run `npm install` to install all dependencies.
Once all dependencies are installed you need to modify `ormconfig.json` and insert your own database settings.
After that you can run your application by running `npm start` command.
After that you can run your application by running `npm start`.
All files are generated inside current directory where you are.
If you want to generate in a specific directory you can use `--name` option:
All files are generated in the current directory.
If you want to generate them in a special directory you can use `--name`:
```
typeorm init --name my-project
```
To specify a specific database you use you can use `--database` option:
To specify a specific database you use you can use `--database`:
```
typeorm init --database mssql
@ -55,13 +55,13 @@ You can also generate a base project with Express:
typeorm init --name my-project --express
```
If you are using docker you can generate a `docker-compose.yml` file using following command:
If you are using docker you can generate a `docker-compose.yml` file using:
```
typeorm init --docker
```
Using `typeorm init` command is the easiest and fastest way to setup a TypeORM project.
`typeorm init` is the easiest and fastest way to setup a TypeORM project.
## Create a new entity
@ -72,8 +72,8 @@ You can create a new entity using CLI:
typeorm entity:create -n User
```
where `User` is entity file and class names.
Running following command will create a new empty entity in `entitiesDir` of the project.
where `User` is entity file and class name.
Running the command will create a new empty entity in `entitiesDir` of the project.
To setup `entitiesDir` of the project you must add it in connection options:
```
@ -84,16 +84,16 @@ To setup `entitiesDir` of the project you must add it in connection options:
}
```
More about connection options [see here](./connection-options.md).
If you have multi-module project structure with multiple entities in different directories
you can provide a path to CLI command where you want to generate an entity:
Learn more about [connection options](./connection-options.md).
If you have a multi-module project structure with multiple entities in different directories
you can provide the path to the CLI command where you want to generate an entity:
```
typeorm entity:create -n User -d src/user/entity
```
More about entities [read here](./entities.md).
Learn more about [entities](./entities.md).
## Create a new subscriber
@ -103,9 +103,9 @@ You can create a new subscriber using CLI:
typeorm subscriber:create -n UserSubscriber
```
where `UserSubscriber` is subscriber file and class names.
Running following command will create a new empty subscriber in `subscribersDir` of the project.
To setup `subscribersDir` of the project you must add it in connection options:
where `UserSubscriber` is subscriber file and class name.
Running following command will create a new empty subscriber in the `subscribersDir` of the project.
To setup `subscribersDir` you must add it in connection options:
```
{
@ -115,28 +115,28 @@ To setup `subscribersDir` of the project you must add it in connection options:
}
```
More about connection options [see here](./connection-options.md).
If you have multi-module project structure with multiple subscribers in different directories
you can provide a path to CLI command where you want to generate a subscriber:
Learn more about [connection options](./connection-options.md).
If you have a multi-module project structure with multiple subscribers in different directories
you can provide a path to the CLI command where you want to generate a subscriber:
```
typeorm subscriber:create -n UserSubscriber -d src/user/subscriber
```
More about subscribers [read here](./listeners-and-subscribers.md).
Learn more about [Subscribers](./listeners-and-subscribers.md).
## Create a new migration
You can create a new migration using CLI:
```
typeorm migration:create -n UserSubscriber
typeorm migration:create -n UserMigration
```
where `UserSubscriber` is migration file and class names.
Running following command will create a new empty migration in `migrationsDir` of the project.
To setup `migrationsDir` of the project you must add it in connection options:
where `UserMigration` is migration file and class name.
Running the command will create a new empty migration in the `migrationsDir` of the project.
To setup `migrationsDir` you must add it in connection options:
```
{
@ -146,28 +146,28 @@ To setup `migrationsDir` of the project you must add it in connection options:
}
```
More about connection options [see here](./connection-options.md).
If you have multi-module project structure with multiple migrations in different directories
you can provide a path to CLI command where you want to generate a migration:
Learn more about [connection options](./connection-options.md).
If you have a multi-module project structure with multiple migrations in different directories
you can provide a path to the CLI command where you want to generate a migration:
```
typeorm migration:create -n UserMigration -d src/user/migration
```
More about migrations [read here](./migrations.md).
Learn more about [Migrations](./migrations.md).
## Generate a migration from exist table schema
Automatic migration generation feature creates a new migration file
and writes there all sql queries schema sync must execute to update a schema.
Automatic migration generation creates a new migration file
and writes all sql queries that must be executed to update the database.
```
typeorm migration:generate -n UserMigration
```
Rule of thumb is to generate migration after each entity change.
Rule of thumb is to generate a migration after each entity change.
More about migrations [read here](./migrations.md).
Learn more about [Migrations](./migrations.md).
## Run migrations
@ -177,7 +177,7 @@ To execute all pending migrations use following command:
typeorm migrations:run
```
More about migrations [read here](./migrations.md).
Learn more about [Migrations](./migrations.md).
## Revert migrations
@ -187,24 +187,24 @@ To revert last executed migration use following command:
typeorm migrations:revert
```
This command will undo only last executed migration.
You can execute this command multiple times to revert on a specific migration run.
More about migrations [read here](./migrations.md).
This command will undo only the last executed migration.
You can execute this command multiple times to revert mutliple migrations.
Learn more about [Migrations](./migrations.md).
## Sync database schema
To synchronize a database schema use following command:
To synchronize a database schema use:
```
typeorm schema:sync
```
Be careful running this command on production -
Be careful running this command in production -
schema sync may bring you data loose if you don't use it wisely.
Check sql queries it will run before running this query on production.
## Log sync database schema queries without actual running them
To check what sql queries `schema:sync` is going to run use following command:
To check what sql queries `schema:sync` is going to run use:
```
typeorm schema:log
@ -212,7 +212,7 @@ typeorm schema:log
## Drop database schema
To complete drop database schema use following command:
To complete drop a database schema use:
```
typeorm schema:drop
@ -222,7 +222,7 @@ Be careful with this command on production since it completely remove data from
## Run any sql query
You can execute any sql query you want directly in the database using following command:
You can execute any sql query you want directly in the database using:
```
typeorm query "SELECT * FROM USERS"
@ -230,8 +230,8 @@ typeorm query "SELECT * FROM USERS"
## Clear cache
If you are using `QueryBuilder` cache, sometimes you may want to clear everything stored in the cache.
You can do it using following command:
If you are using `QueryBuilder` caching, sometimes you may want to clear everything stored in the cache.
You can do it using the following command:
```
typeorm cache:clear
@ -239,7 +239,7 @@ typeorm cache:clear
## Check version
You can check what typeorm version you have installed (both local and global) by running following command:
You can check what typeorm version you have installed (both local and global) by running:
```
typeorm version

View File

@ -11,9 +11,9 @@
Most of the times you want to store your connection options in a separate configuration file.
It makes it convenient and easy to manage.
TypeORM supports multiple configuration sources for this purpose.
You'll only need to create `ormconfig.[format]` file in root directory of your application (near `package.json`),
put your configuration there and in app call `createConnection()` without any configuration passed:
TypeORM supports multiple configuration sources.
You only need to create a `ormconfig.[format]` file in the root directory of your application (near `package.json`),
put your configuration there and in your app call `createConnection()` without any configuration passed:
```typescript
import {createConnection, Connection} from "typeorm";
@ -24,7 +24,7 @@ const connection: Connection = await createConnection();
## Loading from `ormconfig.json`
Create `ormconfig.json` file in project root (near `package.json`). It should have following content:
Create `ormconfig.json` in the project root (near `package.json`). It should have the following content:
```json
{
@ -38,7 +38,7 @@ Create `ormconfig.json` file in project root (near `package.json`). It should ha
```
You can specify any other options from `ConnectionOptions`.
For more information about connection options see [ConnectionOptions](./connection-options.md) documentation.
Learn more about [ConnectionOptions](./connection-options.md).
If you want to create multiple connections then simply create multiple connections in a single array:
@ -64,7 +64,7 @@ If you want to create multiple connections then simply create multiple connectio
## Loading from `ormconfig.js`
Create `ormconfig.js` file in project root (near `package.json`). It should have following content:
Create `ormconfig.js` in the project root (near `package.json`). It should have following content:
```javascript
module.exports = {
@ -82,7 +82,7 @@ If you want to create multiple connections then simply create multiple connectio
## Loading from `ormconfig.env` or from environment variables
Create `ormconfig.env` file in project root (near `package.json`). It should have following content:
Create `ormconfig.env` in the project root (near `package.json`). It should have the following content:
```ini
TYPEORM_CONNECTION = mysql
@ -123,12 +123,12 @@ List of available env variables you can set:
`ormconfig.env` should be used only during development.
On production you can set all these values in real ENVIRONMENT VARIABLES.
You cannot define multiple connections using `env` file or environment variables.
You cannot define multiple connections using an `env` file or environment variables.
If your app has multiple connections then use alternative configuration storage format.
## Loading from `ormconfig.yml`
Create `ormconfig.yml` file in project root (near `package.json`). It should have following content:
Create `ormconfig.yml` in the project root (near `package.json`). It should have the following content:
```yaml
default: # default connection
@ -150,7 +150,7 @@ You can use any connection options available.
## Loading from `ormconfig.xml`
Create `ormconfig.xml` file in project root (near `package.json`). It should have following content:
Create `ormconfig.xml` in the project root (near `package.json`). It should have the following content:
```xml
<connections>

View File

@ -1,6 +1,6 @@
# Using Validation
To use validation use [class-validator](https://github.com/pleerock/class-validator) package.
To use validation use [class-validator](https://github.com/pleerock/class-validator).
Example how to use class-validator with TypeORM:
```typescript

View File

@ -1,9 +1,9 @@
# What is EntityManager
Using `EntityManager` you can manage (insert, update, delete, load, etc.) any entity.
EntityManager is just like collection of all entity repositories in a single place.
EntityManager is just like a collection of all entity repositories in a single place.
You can access entity manager via `getManager()` function or from `Connection` object.
You can access the entity manager via `getManager()` or from `Connection`.
Example how to use it:
```typescript
@ -19,9 +19,9 @@ await entityManager.save(user);
`Repository` is just like `EntityManager` but its operations are limited to a concrete entity.
You can access repository via `getRepository(Entity)` function
or from `Connection#getRepository` or from `EntityManager#getRepository` methods.
Example how to use it:
You can access a repository via `getRepository(Entity)`
or from `Connection#getRepository` or from `EntityManager#getRepository`.
Example:
```typescript
import {getRepository} from "typeorm";

View File

@ -2,9 +2,9 @@
`Repository` is just like `EntityManager` but its operations are limited to a concrete entity.
You can access repository via `getRepository(Entity)` function
or from `Connection#getRepository` or from `EntityManager#getRepository` methods.
Example how to use it:
You can access repository via `getRepository(Entity)`
or from `Connection#getRepository` or from `EntityManager#getRepository`.
Example:
```typescript
import {getRepository} from "typeorm";