Skip to content

Belongs To 关联

介绍

Belongs To 关联表示一个模型属于另一个模型。这是一种多对一的关联关系,通常与 Has OneHas Many 关联配对使用,表示关联关系的反向。

定义 Belongs To 关联

使用 @BelongsTo 装饰器来定义属于关联:

ts
import { Table, Field, FieldType, Model, BelongsTo, HasMany } from '@ibestservices/ibest-orm';

@Table({ name: 'articles' })
class Article extends Model {
  @Field({ type: FieldType.TEXT, tag: ['notNull'] })
  title?: string;

  @Field({ type: FieldType.TEXT })
  content?: string;

  @Field({ type: FieldType.INTEGER, tag: ['notNull'] })
  author_id?: number;

  @Field({ type: FieldType.INTEGER })
  category_id?: number;

  @BelongsTo({
    target: () => User,
    foreignKey: 'author_id',
    localKey: 'id'
  })
  author?: User;

  @BelongsTo({
    target: () => Category,
    foreignKey: 'category_id',
    localKey: 'id'
  })
  category?: Category;

  constructor(title: string, content: string, author_id: number, category_id?: number) {
    super();
    this.title = title;
    this.content = content;
    this.author_id = author_id;
    this.category_id = category_id;
  }
}

@Table({ name: 'users' })
class User extends Model {
  @Field({ type: FieldType.TEXT, tag: ['notNull'] })
  name?: string;

  @Field({ type: FieldType.TEXT })
  email?: string;

  @HasMany({
    target: () => Article,
    foreignKey: 'author_id',
    localKey: 'id'
  })
  articles?: Article[];

  constructor(name: string, email: string) {
    super();
    this.name = name;
    this.email = email;
  }
}

@Table({ name: 'categories' })
class Category extends Model {
  @Field({ type: FieldType.TEXT, tag: ['notNull'] })
  name?: string;

  @Field({ type: FieldType.TEXT })
  description?: string;

  @HasMany({
    target: () => Article,
    foreignKey: 'category_id',
    localKey: 'id'
  })
  articles?: Article[];

  constructor(name: string, description?: string) {
    super();
    this.name = name;
    this.description = description;
  }
}

配置参数

target

  • 类型: () => Class
  • 描述: 目标模型类的工厂函数
  • 必需: 是

foreignKey

  • 类型: string
  • 描述: 当前表中的外键字段名
  • 默认值: ${目标表名}_id
  • 示例: 'author_id', 'category_id'

localKey

  • 类型: string
  • 描述: 目标表中的本地键字段名(通常是主键)
  • 默认值: 'id'
  • 示例: 'id'

查询 Belongs To 关联

预加载关联数据

ts
// 查询文章及其作者信息
const articleWithAuthor = await this.orm.Session(Article)
  .With('author')
  .Where('id', 1)
  .FirstWithRelations();

console.log('文章及作者:', articleWithAuthor);
// 输出:
// {
//   id: 1,
//   title: "TypeScript入门指南",
//   content: "TypeScript是JavaScript的超集...",
//   author_id: 1,
//   author: {
//     id: 1,
//     name: "张三",
//     email: "zhangsan@example.com"
//   }
// }

预加载多个关联

ts
// 查询文章及其作者和分类
const articleWithDetails = await this.orm.Session(Article)
  .With('author', 'category')
  .Where('id', 1)
  .FirstWithRelations();

console.log('文章详情:', articleWithDetails);
// 输出:
// {
//   id: 1,
//   title: "TypeScript入门指南",
//   content: "TypeScript是JavaScript的超集...",
//   author_id: 1,
//   category_id: 1,
//   author: {
//     id: 1,
//     name: "张三",
//     email: "zhangsan@example.com"
//   },
//   category: {
//     id: 1,
//     name: "技术",
//     description: "技术相关文章"
//   }
// }

查询多篇文章的关联数据

ts
// 查询所有文章及其作者
const articlesWithAuthors = await this.orm.Session(Article)
  .With('author')
  .FindWithRelations();

articlesWithAuthors.forEach(article => {
  console.log(`《${article.title}》 作者: ${article.author?.name}`);
});

嵌套关联查询

ts
// 查询文章、作者及作者的档案
const articleWithAuthorProfile = await this.orm.Session(Article)
  .With('author.profile')
  .Where('id', 1)
  .FirstWithRelations();

// 查询评论、文章及文章作者
const commentWithDetails = await this.orm.Session(Comment)
  .With('article.author', 'user')
  .Where('id', 1)
  .FirstWithRelations();

查询技巧

根据关联数据查询

ts
// 查询特定作者的所有文章
const authorArticles = await this.orm.Session(Article)
  .With('author')
  .Where('author_id', 1)
  .FindWithRelations();

// 查询特定分类的所有文章
const categoryArticles = await this.orm.Session(Article)
  .With('category')
  .Where('category_id', 1)
  .FindWithRelations();

注意事项

提示

  • Belongs To 关联通过外键建立关系,外键存储在当前表中
  • 关联数据为 null 时表示没有对应的关联记录
  • 通常与 Has One 或 Has Many 关联配对使用

注意

  • 删除被关联的记录前要检查是否有其他记录依赖它