Categoriesnode orm libraries

Typeorm tutorial with code examples

This tutorial will teach you about the basics of the typeorm library. After reading this article you can easily use the typeorm in your project.

It is a TypeScript ORM library that helps to link your TypeScript application with a relational database. It supports all of the major relational databases like MySql, PostgreSQL, SQLite, etc.

This typeorm tutorial will cover all of the basic concepts like

  1. Database connection
  2. Table/Entity Creation
  3. Table/Entity relations
  4. CRUD Operation

Final Code is attached at the end of the article but you can download the basic code setup with all of the necessary dependencies. 

Download basic project setup

Typeorm database connection

First, we will set up a typeorm connection with a database. Here is the code to connect typeorm with the database

Basic Code

this._appDataSource = new DataSource({
      type: config.dbType,
      host: config.dbHost!,
      port: config.dbPort,
      username: config.dbUsername,
      password: config.dbPassword,
      database: config.dbName,
      entities: this.entities, // here you can pass all of your entities like [User, Product]
      synchronize: true, // makes the entity sync with the database every time you run your application
    });

try {
      await this._appDataSource.initialize();
      console.log("Data Source has been initialized!");
    } catch (err) {
      console.error("Error during Data Source initialization", err);
    }

Complete Code in a class-based approach.

import { DataSource, DeepPartial, EntityTarget, ObjectLiteral } from "typeorm";
import { config } from "../config";

class SetupConnection {
  private _appDataSource: DataSource;
  private _entities = []; // will contain all tables list

  get entities() {
    return this._entities;
  }

  async connect() {
    this._appDataSource = new DataSource({
      type: config.dbType, // postgresql or MySql
      host: config.dbHost!,
      port: config.dbPort,
      username: config.dbUsername,
      password: config.dbPassword,
      database: config.dbName,
      entities: this.entities,
      synchronize: true, 
    });

    try {
      await this._appDataSource.initialize();
      console.log("Data Source has been initialized!");
    } catch (err) {
      console.error("Error during Data Source initialization", err);
    }
  }

  get dataSource() {
    return this._appDataSource;
  }

  async save(
    entity: EntityTarget<ObjectLiteral>,
    record: DeepPartial<ObjectLiteral>
  ) {
    const userRepository = db.dataSource.getRepository(entity);
    await userRepository.save(record);
  }
}

// don't need to create new database connection on each time, one connection is enough to prevent memory out of exception error 
export const db = new SetupConnection();

New table creation in Typeorm

Table creation in typeorm is very easy, you only need to understand a few terminologies to create the tables in typeorm

  1. @entity() creates a new table in a database
  2. extend each class from BaseEntity class also to inherit basic functions like save function
  3. @column() creates a new column in the table. You can also pass params in the column decorator like @column({type: “numeric”})
  4. @PrimaryGeneratedColumn() creates a new primary key column in the table
  5. @CreateDateColumn() help you to create the createdAt column in the table which will help you to track when the record was created.
  6. @UpdateDateColumn() will update the specific column (updatedAt) every time when you update the record

Table creation examples in Typeorm

  1. User Entity/Table
import {
  Column,
  CreateDateColumn,
  Entity,
  PrimaryGeneratedColumn,
  UpdateDateColumn,
  BaseEntity
} from "typeorm";

@Entity()
export class User extends BaseEntity {
  @PrimaryGeneratedColumn()
  id: number;

  @CreateDateColumn()
  createdAt: Date;

  @UpdateDateColumn()
  updatedAt: Date;

  @Column()
  firstName: string;

  @Column()
  lastName: string;

  @Column()
  email: string;

  @Column()
  password: string;

  @Column()
  phoneNumber?: string;
}

2. Profile Entity/Table

import {
  Column,
  CreateDateColumn,
  Entity,
  OneToOne,
  PrimaryGeneratedColumn,
  UpdateDateColumn,
  BaseEntity
} from "typeorm";

@Entity()
export class Profile extends BaseEntity {
  @PrimaryGeneratedColumn()
  id: number;

  @CreateDateColumn()
  createdAt: Date;

  @UpdateDateColumn()
  updatedAt: Date;

  @Column()
  profilePic: string;

  @Column()
  aboutMe: string;

}

3. Product entity/table

import {
  Column,
  CreateDateColumn,
  Entity,
  JoinColumn,
  ManyToOne,
  PrimaryGeneratedColumn,
  UpdateDateColumn,
} from "typeorm";

@Entity()
export class Product extends BaseEntity {
  @PrimaryGeneratedColumn()
  id: number;

  @CreateDateColumn()
  createdAt: Date;

  @UpdateDateColumn()
  updatedAt: Date;

  @Column()
  productPic: string;

  @Column()
  productDescription: string;

  @Column({ type: "numeric" })
  price: number;

}

4. Cart entity/table

import {
  Column,
  CreateDateColumn,
  Entity,
  PrimaryGeneratedColumn,
  UpdateDateColumn,
  BaseEntity
} from "typeorm";

@Entity()
export class Cart extends BaseEntity {
  @PrimaryGeneratedColumn()
  id: number;

  @CreateDateColumn()
  createdAt: Date;

  @UpdateDateColumn()
  updatedAt: Date;
}

You can further read about entities and columns by visiting the official websites. 
https://typeorm.io/entities#entities

After creating the entity class, you need to add it in an entity array. Example

this._appDataSource = new DataSource({
type: config.dbType,
host: config.dbHost!,
port: config.dbPort,
username: config.dbUsername,
password: config.dbPassword,
database: config.dbName,
entities: [User, Product, Cart, Profile],// here pass all of your entities
synchronize: true,
});

Relations in Typeorm

There are 4 relations

  1. one-to-one
  2. one-to-many
  3. many-to-one
  4. many-to-many

One-to-one relation in typeorm

@oneToOne() decorator is used to create one-to-one relations.

Example

1- A user can create only one profile and the profile belong to a specific user only

Add the following code at the end of the User class and import the entity class properly

@OneToOne(() => Profile, (profile) => profile.user)
  profile: Profile;

Add the following code at the end of the Profile class

@OneToOne(() => User, (user) => user.profile)
 @JoinColumn()
  user: User;

Now you have successfully created the one-to-one relationship between a user and the profile

One-to-Many/many-to-one relation in typeorm

@oneToMany() decorator is used when class A has multiple instances of B. Similarly @ManyToOne() is used when the B class has only one instance of A.

Example

Explanation with the help of a user and a product class. In an e-commerce store, a user can add multiple products but a product should belong to one user

Add the following code at the end of the User class

@OneToMany(() => Product, (product) => product.user)
  products: Product[];

Add the following code at the end of the Product class

@ManyToOne(() => User, (user) => user.products)
  // @JoinColumn({ name: "user_id" }) // optional if user want to change the name of the column
  user: User;

Many-to-many relations in typeorm

@manyToMany() a relationship is used when class A has multiple instances of B and B also have.

Example

A product can add to multiple carts and a cart can contain multiple products

Add the following code at the end of the Cart class

@ManyToMany(() => Product)
@JoinTable()
product: Product[];

Winding up typeorm basic tutorial

After creating all the entities and the relationships between them, now add all of the entities in the entity array which is present in SetupConnection class. I have already shared the SetupConnection class code with you, so you can copy that code and update its entity field like

private _entities = [User, Product, Profile, Cart];

After running npm run dev make sure all the following tables must be present in your database

CRUD

How to create a new record in typeorm?

Now, I am sharing the code examples with you so you can understand, how you can insert the record.

Code Examples

const createNewUserRecord = async () => {
const user = new User();
user.firstName = "M Ahmed";
user.lastName = "Mushtaq";
user.email = "email@gmail.com";
user.password = await encodePassword("123@12");
await user.save();
};

Another way to insert a record 

// another way to insert record
const insertNewUser = async () => {
const user = User.create({
firstName: "M Ahmed",
lastName: "Mushtaq",
email: "shine@gmail.com",
password: await encodePassword("234234"),
});

await user.save();
};

How to read a record in typeorm?

import { User } from "../schema/User";
export const readRecord = async () => {
const user = await User.findOneBy({ id: 4 });
console.log("user is ", user);
};

How to update a record in typeorm?

import { User } from "../schema/User";

export const updateRecord = async () => {
await User.update({ id: 3 }, { firstName: "Updated Name" });
};

How to delete a record in typeorm?

import { User } from "../schema/User";

export const deleteRecord = async () => {
await User.delete({ id: 3 });
};

Complete typeorm basic code link

Download complete project

Optional

You can further clean your entity classes by using the inheritance concept. 

  1. Create one Base entity class which will contain the common fields like id, createdAt, and updatedAt
  2. Next time, whenever you need to create an entity class you can extend the base class. In this way, you don’t need to repeat the id, createdAt, and updatedAt fields again and again in every entity class. 

Example

import {
  CreateDateColumn,
  Entity,
  PrimaryGeneratedColumn,
  UpdateDateColumn,
  BaseEntity
} from "typeorm";

@Entity()
export class Base extends BaseEntity {
  @PrimaryGeneratedColumn()
  id: number;

  @CreateDateColumn()
  createdAt: Date;

  @UpdateDateColumn()
  updatedAt: Date;
}
import { JoinTable, ManyToMany } from "typeorm";
import { Product } from "./Product";
import { Base } from "./Base";

export class Cart extends Base {
  @ManyToMany(() => Product)
  @JoinTable()
  product: Product[];
}

Conclusion

In short, in this article, we learn about typeorm database connection setup and relations between entities with code examples. 

If you still have a question you can reach out to me on LinkedIn. I will try my best to answer your question. 

Thank you for reading my article