Introduction
TypeORM is an Object-Relational Mapper (ORM) for TypeScript and JavaScript that simplifies interaction with relational databases. It provides decorators to define relations between different entities or tables, making it easy to handle complex data models.
TypeORM Decorators for Relations
@OneToMany: This defines a one-to-many relationship where one entity can have multiple related entities. For example, oneCoursecan have multipleLessons.@ManyToOne: This defines the inverse side of@OneToMany. For example, manyLessonsbelong to oneCourse.@ManyToMany: This defines a many-to-many relationship. In the case ofUserandCourse, a user can be enrolled in many courses, and a course can have many users. This relationship will require a join table to track the associations.@JoinTable: This decorator is required for many-to-many relationships to specify the table that holds the foreign keys linking the two entities.
A Typical Learning Management System (LMS)
In a Learning Management System (LMS), we typically have entities like User, Course ,Lesson, Enrollment, and Assignment, Grade, which can have various relationships. Let us analyze this relational database design step-by-step with source code of TypeORM Entities.
Entities in the Learning Management System
So a database table (SQL) is represented as an Entity Class (TypeORM).
Let us start creating entities and manage relationships. The relationships between entities like User, Course, Enrollment, and Assignment are represented by decorators like @OneToMany, @ManyToOne, and @ManyToMany.
Entity Relations in the Learning Management System
1. User Entity
The User entity represents a user in the system. A user can be either a student or an instructor. Each user can enroll in multiple courses.
import {
Entity,
PrimaryGeneratedColumn,
Column,
OneToMany,
ManyToMany,
JoinTable,
} from 'typeorm';
import { Enrollment } from './Enrollment';
import { Course } from './Course';
@Entity()
export class User {
//Primary column of table with autoincrement
@PrimaryGeneratedColumn()
id: number;
//other column
@Column()
name: string;
@Column()
email: string;
//This user can have many courses
@OneToMany(() => Enrollment, (enrollment) => enrollment.user)
enrollments: Enrollment[];
@ManyToMany(() => Course)
@JoinTable() // This creates a join table for the many-to-many relation
courses: Course[];
}
2. Course Entity
A Course can have many Lessons and can be enrolled by many Users.
import {
Entity,
PrimaryGeneratedColumn,
Column,
OneToMany,
ManyToMany,
} from 'typeorm';
import { Lesson } from './Lesson';
import { User } from './User';
import { Enrollment } from './Enrollment';
@Entity()
export class Course {
@PrimaryGeneratedColumn()
id: number;
@Column()
title: string;
@OneToMany(() => Lesson, (lesson) => lesson.course)
lessons: Lesson[];
@ManyToMany(() => User)
users: User[];
@OneToMany(() => Enrollment, (enrollment) => enrollment.course)
enrollments: Enrollment[];
}
3. Lesson Entity
A Lesson is linked to a Courseand a course can have multiple lessons.
import {
Entity,
PrimaryGeneratedColumn,
Column,
ManyToOne,
} from 'typeorm';
import { Course } from './Course';
@Entity()
export class Lesson {
@PrimaryGeneratedColumn()
id: number;
@Column()
title: string;
@Column()
content: string;
@ManyToOne(() => Course, (course) => course.lessons)
course: Course;
}
4. Enrollment Entity
The Enrollment entity represents a relationship between a student and a course. A student can enroll in multiple courses.
import {
Entity,
PrimaryGeneratedColumn,
ManyToOne,
JoinColumn,
} from 'typeorm';
import { User } from './User';
import { Course } from './Course';
@Entity()
export class Enrollment {
@PrimaryGeneratedColumn()
id: number;
@ManyToOne(() => User, (user) => user.enrollments)
@JoinColumn()
user: User;
@ManyToOne(() => Course, (course) => course.enrollments)
@JoinColumn()
course: Course;
}
5. Assignment Entity
The Assignment entity represents an assignment for a specific course. In this example, an instructor can create many assignments for a course.
import { Entity, PrimaryGeneratedColumn, Column, ManyToOne } from 'typeorm';
import { Course } from './Course';
@Entity()
export class Assignment {
@PrimaryGeneratedColumn()
id: number;
@Column()
title: string;
@Column()
dueDate: Date;
@ManyToOne(() => Course, (course) => course.assignments)
course: Course;
}
6. Grade Entity
A Grade represents the score given to a user for a particular Assignment.
import {
Entity,
PrimaryGeneratedColumn,
Column,
ManyToOne,
} from 'typeorm';
import { Assignment } from './Assignment';
import { User } from './User';
@Entity()
export class Grade {
@PrimaryGeneratedColumn()
id: number;
@Column()
score: number;
@ManyToOne(() => Assignment, (assignment) => assignment.grades)
assignment: Assignment;
@ManyToOne(() => User, (user) => user.grades)
user: User;
}
By using these relations, we can easily query for courses a user is enrolled in, assignments for a course, or even the instructor of a course. TypeORM handles the complexities of joining tables automatically behind the scenes.
