什么是实体
实体是一个映射到数据库表的类。 你可以通过定义一个新类来创建一个实体,并用
@Entity()
来标记
import {Entity,Column,PrimaryGeneratedColumn} from 'typeorm'
@Entity()
export class Test {
@PrimaryGeneratedColumn()
id:number
@Column()
name:string
@Column()
password:string
@Column()
age:number
}
主列
自动递增的主键
@PrimaryGeneratedColumn()
id:number
自动递增uuid
@PrimaryGeneratedColumn("uuid")
id:number
列类型
@Column({type:"varchar",length:200})
password: string
@Column({ type: "int"})
age: number
@CreateDateColumn({type:"timestamp"})
create_time:Date
列选项
@Column({
type:"varchar",
name:"ipaaa", //数据库表中的列名
nullable:true, //在数据库中使列NULL或NOT NULL。 默认情况下,列是nullable:false
comment:"注释",
select:true, //定义在进行查询时是否默认隐藏此列。 设置为false时,列数据不会显示标准查询。 默认情况下,列是select:true
default:"xxxx", //加数据库级列的DEFAULT值
primary:false, //将列标记为主要列。 使用方式和@ PrimaryColumn相同。
update:true, //指示"save"操作是否更新列值。如果为false,则只能在第一次插入对象时编写该值。 默认值为"true"
collation:"", //定义列排序规则。
})
ip:string
simple-array 列类型
有一种称为
simple-array
的特殊列类型,它可以将原始数组值存储在单个字符串列中。 所有值都以逗号分隔
@Entity()
export class User {
@PrimaryGeneratedColumn()
id: number;
@Column("simple-array")
names: string[];
}
simple-json列类型
还有一个名为
simple-json
的特殊列类型,它可以存储任何可以通过 JSON.stringify 存储在数据库中的值。 当你的数据库中没有 json 类型而你又想存储和加载对象,该类型就很有用了。 例如:
@Entity()
export class User {
@PrimaryGeneratedColumn()
id: number;
@Column("simple-json")
profile: { name: string; nickname: string };
}
屏蔽特定字段的返回
使用 @Column({ select: false })
TypeORM 提供了 select: false
属性,使得 password
默认不被查询到,但在需要时仍可以显式加载。
@Entity('users')
export class User {
@PrimaryGeneratedColumn('uuid')
id: string;
@Column()
username: string;
@Column({ select: false }) // 默认不查询 password 字段
password: string;
@Column()
email: string;
}
查询时显式加载 password
:
const user = await this.userRepository.findOne({
where: { id: userId },
select: ['id', 'username', 'password'], // 显式加载 password
});
使用 select
指定查询字段
如果某些查询仅需要部分字段,可以在 TypeORM 查询时通过 select
显式排除 password
:
const users = await this.userRepository.find({
select: ['id', 'username', 'email'], // 仅查询需要的字段
});
TypeORM的一对一映射
一对一的实体
在这里,用户User表和身份证IdCard表是一对一的关系。
user表的实体设计如下:
import { Column, Entity, PrimaryGeneratedColumn } from 'typeorm';
@Entity('users')
export class User {
@PrimaryGeneratedColumn()
id: number;
@Column({ type: 'varchar', length: 100, comment: '用户名' })
username: string;
}
idcard表的实体设计如下:
import { User } from 'src/modules/user/entities/user.entity';
import {
Column,
Entity,
JoinColumn,
OneToOne,
PrimaryGeneratedColumn,
} from 'typeorm';
@Entity('id_card')
export class IdCard {
@PrimaryGeneratedColumn()
id: number;
@Column({ type: 'varchar', length: 100, comment: '身份证号码' })
cardNumber: string;
// 在 IdCard 的 Entity 添加一个 user 列,指定它和 User 是 @OneToTone 一对一的关系。
// 还要指定 @JoinColum 也就是外键列在 IdCard 对应的表里维护:
@JoinColumn()
@OneToOne(() => User)
user: User;
}
一对一关联查询
import { Injectable } from '@nestjs/common';
import { CreateIdcardDto } from './dto/create-idcard.dto';
import { UpdateIdcardDto } from './dto/update-idcard.dto';
import { InjectEntityManager } from '@nestjs/typeorm';
import { EntityManager } from 'typeorm';
import { IdCard } from './entities/idcard.entity';
@Injectable()
export class IdcardService {
@InjectEntityManager()
private idcardEntityManager: EntityManager;
findAll() {
return this.idcardEntityManager.find(IdCard, {
// user就是在实体加入的JoinColumn列的名称user
relations: ['user'],
// 或者下面的方式也可以
relations: {
user: true
}
});
}
}
查询出来的结果如下:
[
{
"id": 1,
"cardNumber": "42xxxxxxxxxxxx55",
"user": {
"id": 1,
"username": "陈刚"
}
}
]
TypeORM的一对多和多对一的映射
这里我们将
@OneToMany
添加到photos
属性中,并将目标关系类型指定为Photo
。 你可以在@ManyToOne
/@OneToMany
关系中省略@JoinColumn
,除非你需要自定义关联列在数据库中的名称。@ManyToOne
可以单独使用,但@OneToMany
必须搭配@ManyToOne
使用。 如果你想使用@OneToMany
,则需要@ManyToOne
。 在你设置@ManyToOne
的地方,相关实体将有"关联 id"和外键。
多对一/一对多是指 A 包含多个 B 实例的关系,但 B 只包含一个 A 实例。 让我们以User
和 Photo
实体为例。 User 可以拥有多张 photos,但每张 photo 仅由一位 user 拥有。
Photo实体结构如下:
import { User } from 'src/modules/user/entities/user.entity';
import { Column, Entity, ManyToOne, PrimaryGeneratedColumn } from 'typeorm';
@Entity({ name: 'photo' })
export class Photo {
@PrimaryGeneratedColumn()
id: number;
@Column({ comment: '照片地址' })
url: string;
// 一个用户可以拥有多张照片,因此在这里可以理解为Photo对于User是多对一的
@ManyToOne(() => User, (user) => user.photos)
user: User;
}
User实体结构如下:
import { Photo } from 'src/modules/photo/entities/photo.entity';
import { Column, Entity, OneToMany, PrimaryGeneratedColumn } from 'typeorm';
@Entity('users_demo')
export class User {
@PrimaryGeneratedColumn()
id: number;
@Column({ type: 'varchar', length: 100, comment: '用户名' })
username: string;
// 一个用户拥有多张图片,因此在User的实体内部是一对多的关系
@OneToMany(() => Photo, (photo) => photo.user)
photos: Photo[];
}