ORM 提供了一系列抽象方法,可以对象化操作数据库
模型可以理解为数据抽象层,模型提供了许多便捷的数据操作接口
定义一个模型类可以用来描述一个模型, 通过 @Table()
来定义一个模型,下面是一个 User
模型:
import { Table, Column, AutoIncrementPrimaryColumn } from '@tiger/common';
@Table('users')
export class User {
@AutoIncrementPrimaryColumn()
id: number;
@Column()
name: string;
}
通过 Table 的参数来指定映射的表名
通过字段定义可以描述模型对应的数据库字段
import { Table, Column, AutoIncrementPrimaryColumn } from '@tiger/common';
@Table('users')
export class User extends Entity {
@AutoIncrementPrimaryColumn()
id: number;
@Column()
name: string;
@Column()
age: number;
@Column()
gender: 'M' | 'F';
}
每个模型都至少需要配置一个主键
普通主键
import { Table, Column, PrimaryColumn } from '@tiger/common';
@Table('users')
export class User extends Entity {
@PrimaryColumn()
id: number;
@Column()
name: string;
}
自增主键
import { Table, Column, AutoIncrementPrimaryColumn } from '@tiger/common';
@Table('users')
export class User {
@AutoIncrementPrimaryColumn()
id: number;
@Column()
name: string;
}
控制器中可以使用 model
方法来创建
import { Controller, Get, model } from '@tiger/common'
import { UserModel } from '../models/user'
@Controller()
export default class {
@Get()
index() {
const model = model(UserModel)
}
}
或者通过继承 BaseModel
来直接实例化
import { BaseModel, Table, Column, AutoIncrementPrimaryColumn } from '@tiger/common';
@Table('users')
export class UserModel extends BaseModel {
@AutoIncrementPrimaryColumn()
id: number;
@Column()
name: string;
}
直接实例化
import { Controller, Get } from '@tiger/common'
import { UserModel } from '../models/user'
@Controller()
export default class {
@Get()
index() {
const model = new UserModel();
}
}
根据主键值获取单条记录
const user = new UserModel();
const res = await user.get(1);
console.log(res.age)
根据查询构建器获取单条记录
const user = new UserModel();
const res = await user.createQueryBuilder().where('id', 1).first();
console.log(res.age)
遍历主键获取
const user = new UserModel();
for (const id of [1, 2, 3]) {
const res = await user.get(id);
console.log(res.age)
}
使用查询构建器查询
const user = new UserModel();
const res = await user.createQueryBuilder().whereIn('id', [1, 2, 3]).find();
for (const item of res) {
console.log(item.age)
}
模型数据的新增和数据库的新增数据有所区别,数据库的新增只是单纯的写入数据,而模型的新增则会包含自动时间戳,软删除等功能
const user = new UserModel();
user.name = 'tiger';
user.age = 10';
await user.save();
也可以使用 create
方法传入数据对象
const user = new UserModel();
await user.create({
name: 'tiger',
age: 10
});
更新数据前我们需要先取出数据,然后进行更新
const user = new UserModel();
const res = await user.get(1);
res.name = 'tiger'
res.age = 10
await res.save();
save
方法会自动判断是更新还是新增操作不要调用
save
方法进行多次数据写入。
使用 delete
方法删除当前模型, 删除前需要先取出模型
const user = new UserModel();
const res = await user.get(1);
await res.delete();
使用 destroy
根据主键删除模型
const user = new UserModel();
user.destroy(1, 2, 3)
模型支持配置自动插入/更新时间戳字段的能力
该模型在每次创建数据的时候,都会自动插入 created_at
为当前时间戳,默认 int
类型:
import { BaseModel, Table, Column, AutoIncrementPrimaryColumn, CreateTimestampColumn } from '@tiger/common';
@Table('users')
export class UserModel extends BaseModel {
@AutoIncrementPrimaryColumn()
id: number;
@Column()
name: string;
@CreateTimestampColumn()
created_at: number;
}
如果需要修改为其他类型的时间戳字段,可以通过 CreateTimestampColumn
的参数修改
支持 int
、timestamp
、date
、time
、year
、datetime
import { BaseModel, Table, Column, AutoIncrementPrimaryColumn, CreateTimestampColumn } from '@tiger/common';
@Table('users')
export class UserModel extends BaseModel {
@AutoIncrementPrimaryColumn()
id: number;
@Column()
name: string;
@CreateTimestampColumn('timestamp')
created_at: string;
}
该模型在每次更新数据的时候,都会自动修改 updated_at
为当前时间戳,默认 int
类型:
import { BaseModel, Table, Column, AutoIncrementPrimaryColumn, UpdateTimestampColumn } from '@tiger/common';
@Table('users')
export class UserModel extends BaseModel {
@AutoIncrementPrimaryColumn()
id: number;
@Column()
name: string;
@UpdateTimestampColumn()
updated_at: number;
}
在实际项目中,对数据频繁使用删除操作会导致性能问题,软删除的作用就是把数据加上删除标记,而不是真正的删除,同时也便于需要的时候进行数据的恢复
通过配置软删除字段来开启软删除功能, 示例模型在删除操作的时候会自动更新 deleted_at
字段为当前时间戳,默认 int
类型
import { BaseModel, Table, Column, AutoIncrementPrimaryColumn, SoftDeleteColumn } from '@tiger/common';
@Table('users')
export class UserModel extends BaseModel {
@AutoIncrementPrimaryColumn()
id: number;
@Column()
name: string;
@SoftDeleteColumn()
deleted_at: number;
}
定义好模型后,我们就可以通过模型的删除方法来进行删除操作, 数据并不会在数据库中真实删除:
const user = new UserModel();
const res = await user.get(1);
await res.delete();
并且无法直接查询该数据
const user = new UserModel();
await user.destory(1);
const res = await user.get(1);
console.log(res)
一般通过模型查询到的结果否是模型实例, 我们可以通过模型方法来获取模型的真实数据
getAttribute(name)
根据字段名获取字段值
const user = new UserModel();
const res = await user.get(1);
console.log(res.getAttribute('age'))
getAttributes()
获取模型数据
const user = new UserModel();
const res = await user.get(1);
console.log(res.getAttributes())
通过模型关联操作把数据表的关联关系对象化,关联操作比起常规的数据库联表操作更加直观
使用 hasOne(() => Model, { foreignKey: string, localKey: string })
来定义一对一的模型关联,第一个参数接收一个返回关联模型类的匿名函数 (为了解决循环依赖的问题), foreignKey
用来定义自定义外键名, 默认使用 关联模型表名的单数形式_id
, localKey
用来定义主键名, 默认当前模型主键名
定义 User
模型
import { BaseModel, Table, AutoIncrementPrimaryColumn, Column, HasOne } from '@tiger/common';
import { ProfileModel } from './profile';
@Table('users')
export class UserModel extends BaseModel {
@AutoIncrementPrimaryColumn()
id: number;
@Column()
name: string;
@HasOne(() => Profile)
profile: ProfileModel;
}
定义 Profile
模型, 使用 belongsTo()
定义一对一的反向模型关联
import { BaseModel, Table, AutoIncrementPrimaryColumn, Column, BelongsTo } from '@tiger/common';
import { UserModel } from './user';
@Table('users')
export class ProfileModel extends BaseModel {
@AutoIncrementPrimaryColumn()
id: number;
@Column()
name: string;
@BelongsTo(() => User)
user: UserModel;
}
使用 hasMany(() => Model, { foreignKey: string, localKey: string })
来定义一对多的模型关联,第一个参数接收一个返回关联模型类的匿名函数, foreignKey
用来定义自定义外键名, 默认使用 关联模型表名的单数形式_id
, localKey
用来定义主键名, 默认当前模型主键名
定义 User
模型
import { BaseModel, Table, AutoIncrementPrimaryColumn, Column, HasMany } from '@tiger/common';
import { ProfileModel } from './profile';
@Table('users')
export class UserModel extends BaseModel {
@AutoIncrementPrimaryColumn()
id: number;
@Column()
name: string;
@hasMany(() => ProfileModel)
profiles: ProfileModel[];
}
定义 Profile
模型, 使用 BelongsTo()
定义一对一的反向模型关联
import { BaseModel, Table, AutoIncrementPrimaryColumn, Column, BelongsTo } from '@tiger/common';
import { UserModel } from './user';
@Table('users')
export class ProfileModel extends BaseModel {
@AutoIncrementPrimaryColumn()
id: number;
@Column()
name: string;
@BelongsTo(() => UserModel)
user: UserModel;
}
使用 hasMany(() => Model, { foreignKey: string, localKey: string })
来定义多对多的模型关联,第一个参数接收一个返回关联模型类的匿名函数, foreignPivotKey
用来定义中间表外键名, 默认使用 主表名的单数形式_id
, relatedPivotKey
用来定义中间表关联外键名, 默认使用 关联表名的单数形式_id
定义 User
模型
import { BaseModel, Table, AutoIncrementPrimaryColumn, Column, BelongsToMany } from '@tiger/common';
import { ProfileModel } from './profile';
@Table('users')
export class UserModel extends BaseModel {
@AutoIncrementPrimaryColumn()
id: number;
@Column()
name: string;
@BelongsToMany(() => ProfileModel)
profiles: ProfileModel[];
}
定义 Profile
模型, 使用 belongsToMany()
定义多对多的反向模型关联
import { BaseModel, Table, AutoIncrementPrimaryColumn, Column, BelongsToMany } from '@tiger/common';
import { UserModel } from './user';
@Table('users')
export class ProfileModel extends BaseModel {
@AutoIncrementPrimaryColumn()
id: number;
@Column()
name: string;
@BelongsToMany(() => User)
users: UserModel[];
}
使用 with
方法查询关联数据
const user = new UserModel();
const res = await user.with('profile').get(1);
console.log(res)