Skip to content

Belongs To 关联

介绍

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

定义 Belongs To 关联

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

ts
import { Table, Column, PrimaryKey, BelongsTo, HasMany, ColumnType } from '@ibestservices/ibest-orm';

@Table()
class Article {
  @PrimaryKey()
  id?: number;

  @Column()
  title!: string;

  @Column()
  content?: string;

  @Column({ name: 'author_id', type: ColumnType.INTEGER })
  authorId?: number;

  @Column({ name: 'category_id', type: ColumnType.INTEGER })
  categoryId?: number;

  // 文章属于一个作者
  @BelongsTo(() => User, { foreignKey: 'authorId' })
  author?: User;

  // 文章属于一个分类
  @BelongsTo(() => Category, { foreignKey: 'categoryId' })
  category?: Category;
}

@Table()
class User {
  @PrimaryKey()
  id?: number;

  @Column()
  name!: string;

  @Column()
  email?: string;

  // 用户有多篇文章
  @HasMany(() => Article, { foreignKey: 'author_id' })
  articles?: Article[];
}

@Table()
class Category {
  @PrimaryKey()
  id?: number;

  @Column()
  name!: string;

  @Column()
  description?: string;

  // 分类下有多篇文章
  @HasMany(() => Article, { foreignKey: 'category_id' })
  articles?: Article[];
}

配置参数

target(第一个参数)

  • 类型: () => ClassClass
  • 描述: 目标模型类或返回目标模型类的工厂函数
  • 必需: 是
  • 示例: () => User

options(第二个参数)

foreignKey

  • 类型: string
  • 描述: 当前表中的外键字段名(属性名,非数据库列名)
  • 默认值: ${属性名}_id(自动推断)
  • 示例: 'authorId', 'categoryId'

localKey

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

lazy

  • 类型: boolean
  • 描述: 是否延迟加载
  • 默认值: true

查询 Belongs To 关联

预加载关联数据

ts
import { getORM } from '@ibestservices/ibest-orm';

const orm = getORM();

// 查询文章及其作者信息
const articles = orm.query(Article)
  .with('author')
  .find();

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

预加载多个关联

ts
// 查询文章及其作者和分类
const article = orm.query(Article)
  .with('author')
  .with('category')
  .where({ id: 1 })
  .first();

console.log('文章详情:', article);
// 输出:
// {
//   id: 1,
//   title: "TypeScript入门指南",
//   authorId: 1,
//   categoryId: 1,
//   author: { id: 1, name: "张三" },
//   category: { id: 1, name: "技术" }
// }

查询多篇文章的关联数据

ts
// 查询所有文章及其作者
const articles = orm.query(Article)
  .with('author')
  .find();

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

完整示例

ts
import {
  Table, Column, PrimaryKey, BelongsTo, HasMany,
  initORMWithMemory, getORM, ColumnType
} from '@ibestservices/ibest-orm';

// 定义模型
@Table()
class Post {
  @PrimaryKey()
  id?: number;

  @Column()
  title!: string;

  @Column({ name: 'user_id', type: ColumnType.INTEGER })
  userId?: number;

  @BelongsTo(() => User, { foreignKey: 'userId' })
  user?: User;
}

@Table()
class User {
  @PrimaryKey()
  id?: number;

  @Column()
  name!: string;

  @HasMany(() => Post, { foreignKey: 'user_id' })
  posts?: Post[];
}

// 初始化
const orm = initORMWithMemory();
orm.migrate(User, Post);

// 创建数据
const user = new User();
user.name = '张三';
const userId = orm.insert(user);

const post = new Post();
post.title = '我的第一篇文章';
post.userId = userId;
orm.insert(post);

// 查询文章及其作者
const posts = orm.query(Post).with('user').find();
console.log(posts[0]?.user?.name); // '张三'

// 查询用户及其文章
const users = orm.query(User).with('posts').find();
console.log(users[0]?.posts?.length); // 1

注意事项

提示

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

注意

  • foreignKey 参数使用属性名(camelCase),而非数据库列名(snake_case)
  • 删除被关联的记录前要检查是否有其他记录依赖它