TypeORM
TypeORM is an Object-Relational Mapper for TypeScript and JavaScript. It makes the
user interact with database using classes and objects instead of writing raw SQL
queries.
Supports TypeScript natively.
Works with all SQL and NoSQL databases.
We use TypeScript code to create a database where tables:
o Tables => Classes
o Rows => Objects
Installation and Setup of TypeORM:
Installation Packages:
o npm install typeorm reflect-metadata
“typeorm” => Core TypeORM library
“reflect-metadata” => Needed for TypeScript decorators to work
o npm install mysql2
“mysql2” => MySQL driver for Node.js
tsconfig.json Setup:
{
"experimentalDecorators": true,
"emitDecoratorMetadata": true
}
o “"experimentalDecorators": true” => Enables decorators like @Entity()
o “"emitDecoratorMetadata": true” => TypeScript generate metadata that
TypeORM needs to mapclasses to database tables.
Database Connection:
import "reflect-metadata";
import { DataSource } from "typeorm";
import { User } from "./User";
export const AppDataSource = new DataSource({
type: "mysql",
host: "localhost",
port: 3306,
username: "root",
password: "password",
database: "test_db",
synchronize: true,
logging: true,
entities: [User],
});
o “import "reflect-metadata";” => Loads metadata that required for TypeORM
decorators.
o “import { DataSource } from "typeorm";” => Imports the TypeORM class
used for configure.
o “import { User } from "./User";” => Imports the entity class so TypeORM
knows which tables to manage.
o “type: "mysql"” => Type of the database.
o “entities: [User]” => Array of entity classes to map to database tables.
Defining an Entity (User):
import { Entity, PrimaryGeneratedColumn, Column } from "typeorm";
//import { Entity, PrimaryGeneratedColumn, Column, Unique } from
"typeorm";
@Entity()
//@Unique(["name", "email"])
export class User {
@PrimaryGeneratedColumn()
id: number;
@Column()
name: string;
@Column({ unique: true })
email: string;
}
o “Entity” => Decorator marking this class as a table.
o “PrimaryGeneratedColumn” => Decorator for auto-incrementing primary key.
o “Column” => Decorator for normal table columns.
o “@Entity()” => Marks User as a table in the database.
o “@PrimaryGeneratedColumn()” => Auto-generated ID for each user row.
o “id: number;” => Property representing the ID column.
o “@Column()” => Marks name as a column in the table.
o “name: string;” => Property representing the user’s name.
o “unique: true” => Creates a unique constraint on this column in the database.
o “@Unique([...columns])” => Ensures that the combination of listed columns
is unique.
Initializing and Repository Setup:
import { AppDataSource } from "./data-source";
import { User } from "./User";
AppDataSource.initialize()
.then(async () => {
console.log("Data Source has been initialized!");
const userRepo = AppDataSource.getRepository(User);
const newUser = userRepo.create({ name: "John Doe", email:
"
[email protected]" });
await userRepo.save(newUser);
const users = await userRepo.find();
console.log(users);
})
.catch((error) => console.log(error));
o First two lines are importing statements of database connection and entity
class.
o “AppDataSource.initialize()” => Opens connection to the database.
o “const userRepo = AppDataSource.getRepository(User);” => Fetches the
repository object that handles all CRUD operations for User.
o “create()” => Creates a new instance of the User entity but doesn’t save it.
o “save()” => Inserts the new instance or user into the database.
o “find()” => Retrieves all rows from the User table.
Difference between TypeORM and Sequelize:
TypeORM Sequelize
TypeScript-first (built with TS in JavaScript-first (TS support via
mind). typings).
Uses decorators (@Entity, @Column) Uses model definitions (Model.init)
Repository pattern (repo.find(), Model methods (User.findAll(),
repo.save()) User.create())
Strong type safety (native TS) Weaker type safety (extra typings
needed)
TypeScript + OOP-style projects Mature JS projects needing stability
& flexibility
If your large project is TypeScript- If your large project is JavaScript-
heavy (e.g., NestJS backend, first (e.g., Express, Koa, legacy
microservices, domain-driven design) migration, huge team with JS
=> TypeORM is better. background) => Sequelize is safer.
Defining an Entity (User): Defining an Entity (User):
import { Entity, import { DataTypes, Model,
PrimaryGeneratedColumn, Column } Optional } from "sequelize";
from "typeorm"; import { sequelize } from
"../sequelize";
@Entity()
export class User { interface UserAttributes {
@PrimaryGeneratedColumn() id: number;
id: number; name: string;
email: string;
@Column() }
name: string;
interface UserCreationAttributes
@Column({ unique: true }) extends Optional<UserAttributes,
email: string; "id"> {}
}
export class User extends
Data Connection: Model<UserAttributes,
import "reflect-metadata"; UserCreationAttributes>
import { DataSource } from implements UserAttributes {
"typeorm"; public id!: number;
import { User } from "./User"; public name!: string;
public email!: string;
export const AppDataSource = new }
DataSource({
type: "mysql", User.init(
host: "localhost", {
port: 3306, id: {
username: "root", type:
password: "password", DataTypes.INTEGER.UNSIGNED,
database: "test_db", autoIncrement: true,
synchronize: true, primaryKey: true,
logging: true, },
entities: [User], name: {
}); type: new
DataTypes.STRING(128),
allowNull: false,
},
email: {
type: new
DataTypes.STRING(128),
allowNull: false,
unique: true,
},
},
{
sequelize,
tableName: "users",
modelName: "User",
timestamps: false,
}
);
Data Connection:
import { Sequelize } from
"sequelize";
export const sequelize = new
Sequelize("test_db", "root",
"password", {
host: "localhost",
dialect: "mysql",
});