联查

假设有以下实体:

  1. import { Entity, PrimaryGeneratedColumn, Column, OneToMany } from "typeorm";
  2. import { Photo } from "./Photo";
  3. @Entity()
  4. export class User {
  5. @PrimaryGeneratedColumn()
  6. id: number;
  7. @Column()
  8. name: string;
  9. @OneToMany(type => Photo, photo => photo.user)
  10. photos: Photo[];
  11. }
  1. import { Entity, PrimaryGeneratedColumn, Column, ManyToOne } from "typeorm";
  2. import { User } from "./User";
  3. @Entity()
  4. export class Photo {
  5. @PrimaryGeneratedColumn()
  6. id: number;
  7. @Column()
  8. url: string;
  9. @ManyToOne(type => User, user => user.photos)
  10. user: User;
  11. }

现在让我们假设你要用用户”Timber”加载他所有的 photos:

  1. const user = await createQueryBuilder("user")
  2. .leftJoinAndSelect("user.photos", "photo")
  3. .where("user.name = :name", { name: "Timber" })
  4. .getOne();

你将会得到以下结果:

  1. {
  2. id: 1,
  3. name: "Timber",
  4. photos: [{
  5. id: 1,
  6. url: "me-with-chakram.jpg"
  7. }, {
  8. id: 2,
  9. url: "me-with-trees.jpg"
  10. }]
  11. }

你可以看到leftJoinAndSelect自动加载了所有 Timber 的 photos。第一个参数是你要加载的关系,第二个参数是你为此关系的表分配的别名。你可以在查询构建器中的任何位置使用此别名。例如,让我们获得所有未删除的 Timber 的 photos。

  1. const user = await createQueryBuilder("user")
  2. .leftJoinAndSelect("user.photos", "photo")
  3. .where("user.name = :name", { name: "Timber" })
  4. .andWhere("photo.isRemoved = :isRemoved", { isRemoved: false })
  5. .getOne();

将会生成以下 SQL 查询:

  1. SELECT user.*, photo.* FROM users user
  2. LEFT JOIN photos photo ON photo.user = user.id
  3. WHERE user.name = 'Timber' AND photo.isRemoved = FALSE

你还可以向连接表达式添加条件,而不是使用”where”:

  1. const user = await createQueryBuilder("user")
  2. .leftJoinAndSelect("user.photos", "photo", "photo.isRemoved = :isRemoved", { isRemoved: false })
  3. .where("user.name = :name", { name: "Timber" })
  4. .getOne();

这将生成以下 sql 查询:

  1. SELECT user.*, photo.* FROM users user
  2. LEFT JOIN photos photo ON photo.user = user.id AND photo.isRemoved = FALSE
  3. WHERE user.name = 'Timber'