Has One 关联
介绍
Has One 关联表示一个模型拥有另一个模型的单个实例。这是一种一对一的关联关系,通常用于将一个表的数据扩展到另一个表中。
定义 Has One 关联
使用 @HasOne 装饰器来定义一对一关联:
ts
import { Table, Column, PrimaryKey, HasOne, BelongsTo, ColumnType } from '@ibestservices/ibest-orm';
@Table()
class User {
@PrimaryKey()
id?: number;
@Column()
name!: string;
@Column()
email?: string;
// 一对一关联:用户有一个档案
@HasOne(() => UserProfile, { foreignKey: 'user_id' })
profile?: UserProfile;
}
@Table({ name: 'user_profiles' })
class UserProfile {
@PrimaryKey()
id?: number;
@Column({ name: 'user_id', type: ColumnType.INTEGER })
userId?: number;
@Column()
avatar?: string;
@Column()
bio?: string;
// 反向关联:档案属于一个用户
@BelongsTo(() => User, { foreignKey: 'userId' })
user?: User;
}配置参数
target(第一个参数)
- 类型:
() => Class或Class - 描述: 目标模型类或返回目标模型类的工厂函数
- 必需: 是
- 示例:
() => UserProfile
options(第二个参数)
foreignKey
- 类型:
string - 描述: 目标表中的外键字段名(数据库列名)
- 默认值:
${当前表名}_id(自动推断) - 示例:
'user_id'
localKey
- 类型:
string - 描述: 当前表中的本地键字段名(通常是主键)
- 默认值:
'id'
lazy
- 类型:
boolean - 描述: 是否延迟加载
- 默认值:
true
查询 Has One 关联
预加载关联数据
ts
import { getORM } from '@ibestservices/ibest-orm';
const orm = getORM();
// 查询用户及其档案信息
const user = orm.query(User)
.with('profile')
.where({ id: 1 })
.first();
console.log('用户信息:', user);
// 输出:
// {
// id: 1,
// name: "张三",
// email: "zhangsan@example.com",
// profile: {
// id: 1,
// userId: 1,
// avatar: "avatar1.jpg",
// bio: "热爱技术的程序员"
// }
// }查询多个用户的关联数据
ts
// 查询所有用户及其档案
const users = orm.query(User)
.with('profile')
.find();
users.forEach(user => {
console.log(`用户 ${user.name} 的头像: ${user.profile?.avatar}`);
});完整示例
ts
import {
Table, Column, PrimaryKey, HasOne, BelongsTo,
initORMWithMemory, getORM, ColumnType
} from '@ibestservices/ibest-orm';
// 定义模型
@Table()
class Employee {
@PrimaryKey()
id?: number;
@Column()
name!: string;
@HasOne(() => EmployeeDetail, { foreignKey: 'employee_id' })
detail?: EmployeeDetail;
}
@Table({ name: 'employee_details' })
class EmployeeDetail {
@PrimaryKey()
id?: number;
@Column({ name: 'employee_id', type: ColumnType.INTEGER })
employeeId?: number;
@Column()
address?: string;
@Column()
phone?: string;
@BelongsTo(() => Employee, { foreignKey: 'employeeId' })
employee?: Employee;
}
// 初始化
const orm = initORMWithMemory();
orm.migrate(Employee, EmployeeDetail);
// 创建数据
const emp = new Employee();
emp.name = '张三';
const empId = orm.insert(emp);
const detail = new EmployeeDetail();
detail.employeeId = empId;
detail.address = '北京市朝阳区';
detail.phone = '13800138000';
orm.insert(detail);
// 查询员工及其详情
const employees = orm.query(Employee).with('detail').find();
console.log(employees[0]?.detail?.address); // '北京市朝阳区'注意事项
提示
- Has One 关联通过外键建立关系,确保外键字段存在
- 预加载查询会执行两次 SQL 查询:先查主表,再查关联表
- 关联数据为 null/undefined 时表示没有对应的关联记录
注意
- 外键字段应该有适当的索引以提高查询性能
- 删除主记录时要考虑关联数据的处理
- 一对一关联中,关联表的外键应该是唯一的