Node.js - TypeORM support
Introduction
TypeORM is an ORM that can run in NodeJS, Browser, Cordova, PhoneGap, Ionic, React Native, NativeScript, Expo, and Electron platforms and can be used with TypeScript - see https://typeorm.io/ for more information.
Objects
TypeORM can be used both with SQL and NoSQL databases.
-
For the SQL:
- a
NodeJS Entity
object when the decoratorEntity
attached to a class declaration or anEntitySchema
instance is found; - a
NodeJS Entity Operation
object when one of the supported TypeORM APIs is used and linked to one of the entities; - a
TypeScript SQL Query
object when the APIsquery
orcreateQueryBuilder
is found.
- a
-
For the NoSQL, the only NoSQL database supported is MongoDB.
- a
NodeJS MongoDB connection
object when the APIscreateConnection
,createConnections
, or aDataSource
instance is found. The name of connection is constructed from the host and database values; - a
NodeJS MongoDB collection
object when the decoratorEntity
attached to a class declaration or anEntitySchema
instance is found, and linked to one of the connections.
- a
Icon | Description |
---|---|
NodeJS Entity | |
NodeJS Entity Operation | |
TypeScript SQL Query | |
NodeJS MongoDB connection | |
NodeJS MongoDB collection |
Supported persistence SQL databases
Supported operations
Entity Operation | Supported APIs |
---|---|
Add |
|
Update |
|
Remove |
|
Select |
|
TypeORM provide several ways to access and/or update a table. One can use:
- an entity manager: getManager, getConnection().manager, DataSource().manager;
- a repository: getRepository, getManager().getRepository, DataSource().getRepository;
- a query builder: getConnection().createQueryBuilder, getManager().createQueryBuilder, getRepository().createQueryBuilder, DataSource().createQueryBuilder, DataSource().manager.createQueryBuilder, DataSource().getRepository().createQueryBuilder.
The use of InjectRepository from @nestjs/typeorm is also supported.
Supported links
Link Type | Caller type | Callee type | Comment |
---|---|---|---|
callLink |
|
|
|
relyonLink |
|
|
When the entity is defined using the decorator ‘Entity’ attached to a class declaration. |
useInsertLink |
|
|
Created by SQL Analyzer when DDL source files are analyzed or by Missing tables and procedures for Node.js when the object is not analyzed. |
useUpdateLink |
|
|
Created by SQL Analyzer when DDL source files are analyzed or by Missing tables and procedures for Node.js when the object is not analyzed. |
useDeleteLink |
|
|
Created by SQL Analyzer when DDL source files are analyzed or by Missing tables and procedures for Node.js when the object is not analyzed. |
useSelectLink |
|
|
Created by SQL Analyzer when DDL source files are analyzed or by Missing tables and procedures for Node.js when the object is not analyzed. |
Cascades
In the following example, the ‘User’ entity has its column profile with a one-to-one relation with the ‘Profile’ entity and cascade set to true:
import { Entity, PrimaryGeneratedColumn, Column } from "typeorm";
@Entity()
export class Profile {
@PrimaryGeneratedColumn()
id: number;
@Column()
gender: string;
@Column()
photo: string;
}
import { Entity, PrimaryGeneratedColumn, Column, OneToOne, JoinColumn } from "typeorm";
import { Profile } from "./profile";
@Entity()
export class User {
@PrimaryGeneratedColumn()
id: number;
@Column()
name: string;
@OneToOne(type => Profile, {
cascade: true
})
@JoinColumn()
profile: Profile;
}
When the profile column of a user instance is saved, if the profile column of that instance was updated with a profile instance, that profile instance is also saved.
import { getRepository } from "typeorm";
import { User } from "../entity_dir/user";
import { Profile } from "../entity_dir/profile";
function update_user(){
const userRepository = getRepository(User);
const user = await userRepository.findOne(1);
const profile = new Profile()
user.name = "fooname";
user.profile = profile
await userRepository.save(user);
}
In this example, two ‘NodeJS Entity’ and three ‘NodeJS Entity Operation’ objects are created. Two ‘relyOn’ links are added when ‘User’ and ‘Profile’ entities are created from their classes. Three ‘call’ links are added from ‘update_user’ function to three ‘NodeJS Entity Operation’ objects. Two ‘useUpdate’ and one ‘useSelect’ links are added between the ‘NodeJS Entity Operation’ objects and both the ‘user’ and ‘profile’ tables:
SQL Queries
SQL queries can also be carried out using TypeORM such as with the following code:
import { getManager } from "typeorm";
import { User } from "../entity_dir/user";
import { getConnection } from "typeorm";
export class AuthService {
private userRepository = getRepository(User);
signUp = async (userData: CreateUserDTO) => {
const { username, email, password } = userData;
const existingUser = await this.userRepository
.createQueryBuilder()
.where('username = :username OR email = :email', { username, email })
.getMany();
};
public foo() {
const manager = getConnection().manager;
const rawData = await manager.query(`SELECT * FROM USER`);
}
}
In this example, two ‘TypeScript SQL Query’ objects are created, and two callLink between the two methods and these queries are added. The SQL Analyzer or by Missing tables and procedures for Node.js can then link these queries to the corresponding table:
Supported persistence MongoDB database
Supported links
Link Type | Caller type | Callee type | Supported APIs |
---|---|---|---|
useInsertLink |
|
|
|
useUpdateLink |
|
|
|
useDeleteLink |
|
|
|
useSelectLink |
|
|
|
TypeORM provide several ways to access and/or update a collection. One can use:
- an entity manager: getMongoManager, getConnection().mongoManager, DataSource().manager;
- a repository: getMongoRepository, getConnection().getMongoRepository, DataSource().getRepository.
The use of InjectRepository from @nestjs/typeorm is also supported.
Link to collection
In the following example, a ‘NodeJS MongoDB connection’ object is created.
import { DataSource } from "typeorm";
export const myDataSource = new DataSource({
type: "mongodb",
host: "localhost",
port: 3306,
username: "root",
password: "admin",
database: "test",
entities: [
"../entity_dir/*.ts"
],
synchronize: true,
logging: false
})
When a MongoDB database is used, for each entity, the extension creates a ‘NodeJS MongoDB collection’ object. A parentLink between that collection and the corresponding connection is added.
import {Entity, PrimaryGeneratedColumn, Column} from "typeorm";
@Entity()
export class User {
@PrimaryGeneratedColumn()
id: number;
@Column()
firstName: string;
@Column()
lastName: string;
@Column()
isActive: boolean;
}
TypeORM provides several ways to access and/or update a collection. Here is an example with a repository:
import { myDataSource } from "./create_connection_datasource";
import { User } from "../entity_dir/user";
function update_user(){
const userRepository = myDataSource.getRepository(User);
const user = await userRepository.findOne({
id: 1,
})
user.name = "fooname";
await userRepository.save(user);
}
Both ‘useSelect’ and ‘useUpdate’ links are created between the ‘update_user’ function and the ‘User’ collection which belongs to the ‘mongodb://localhost/test’ connection:
Known limitations
The following features are not supported
- use of ormconfigs.yml, ormconfigs.env and ormconfigs.xm ORM configuration files
- custom repositories
- view entities
- entity listeners and subscribers
- connectionManager