In TypeORM, implementing multiple JOINs primarily relies on using QueryBuilder or defining relationships in decorators (such as @ManyToOne, @OneToMany, etc.), and then using the find or findOne methods to load these relationships. I will explain both approaches: using QueryBuilder and decorator-based relationship loading for multiple JOINs.
Implementing Multiple JOINs with QueryBuilder
Using QueryBuilder, you can construct more flexible SQL queries, especially for complex JOIN operations. Here is an example using QueryBuilder to implement multiple JOINs:
Assume we have three entities: User, Profile, and Photo, where:
Userhas manyProfileentitiesProfilehas manyPhotoentities
typescriptimport { getConnection } from "typeorm"; // Using QueryBuilder to implement multiple JOINs const users = await getConnection() .createQueryBuilder() .select("user") .from(User, "user") .leftJoinAndSelect("user.profiles", "profile") .leftJoinAndSelect("profile.photos", "photo") .getMany();
In this query:
leftJoinAndSelect("user.profiles", "profile")joins theUserentity with theProfileentity and automatically selects all fields ofProfile.leftJoinAndSelect("profile.photos", "photo")joins theProfileentity with thePhotoentity on top of the existing join, and selects all fields ofPhoto.
Using Decorator-Based Relationship Loading to Implement Multiple JOINs
If you have already defined relationships in your entity classes, you can use the find or findOne methods with the relations option to automatically handle JOIN operations. For example:
typescriptimport { getRepository } from "typeorm"; // Using find method and relations option to automatically load relationships const users = await getRepository(User).find({ relations: ["profiles", "profiles.photos"] });
In this example:
relations: ["profiles", "profiles.photos"]specifies the relationship paths to load. TypeORM automatically handles the necessary JOIN operations and loads eachUser'sProfileand eachProfile'sPhoto.
Summary
By using QueryBuilder or defining relationships in entity classes with decorators, and then loading these relationships via the find method, TypeORM provides a flexible and powerful way to execute complex database queries, including multiple JOIN operations. Both approaches have their advantages: QueryBuilder offers higher flexibility and control, while decorator-based relationship loading and the find method provide a simpler and faster way to handle routine relationship loading.