实体(Entities)

您所在的位置:网站首页 undorable有实体吗 实体(Entities)

实体(Entities)

2024-07-12 00:06| 来源: 网络整理| 查看: 265

实体(Entities)什么是实体?实体列主列特殊列空间列列类型mysql / mariadb的列类型postgres的列类型cockroachdb的列类型sqlite / cordova / react-native / expo的列类型mssql的列类型enum列类型simple-array列类型simple-json列类型生成值的列列选项什么是实体?​

实体是映射到数据库表(或在使用MongoDB时映射到集合)的类。 您可以通过定义一个新类并使用@Entity()标记它来创建实体:

import { Entity, PrimaryGeneratedColumn, Column } from "typeorm"@Entity()export class User { @PrimaryGeneratedColumn() id: number @Column() firstName: string @Column() lastName: string @Column() isActive: boolean}

这将创建以下数据库表:

+-------------+--------------+----------------------------+| user |+-------------+--------------+----------------------------+| id | int(11) | PRIMARY KEY AUTO_INCREMENT || firstName | varchar(255) | || lastName | varchar(255) | || isActive | boolean | |+-------------+--------------+----------------------------+

基本实体由列和关系组成。 每个实体必须具有主列(如果使用MongoDB,则是ObjectId列)。

每个实体必须在数据源选项中注册:

import { DataSource } from "typeorm"import { User } from "./entity/User"const myDataSource = new DataSource({ type: "mysql", host: "localhost", port: 3306, username: "test", password: "test", database: "test", entities: [User],})

或者您可以指定包含所有实体的整个目录 - 所有实体都将被加载:

import { DataSource } from "typeorm"const dataSource = new DataSource({ type: "mysql", host: "localhost", port: 3306, username: "test", password: "test", database: "test", entities: ["entity/*.js"],})

如果要为User实体设置替代表名,可以在@Entity中指定:@Entity("my_users")。 如果要为应用程序中的所有数据库表设置基本前缀,可以在数据源选项中指定entityPrefix。

在使用实体构造函数时,其参数**必须是可选的。由于ORM在从数据库加载时创建实体类的实例,因此不知道您的构造函数参数。

有关参数@Entity的详细信息,请参阅装饰器参考。

实体列​

由于数据库表由列组成,因此您的实体也必须由列组成。 您使用@Column标记的每个实体类属性都将映射到数据库表列。

主键列​

每个实体必须至少有一个主键列。 有几种类型的主键列:

@PrimaryColumn() 创建一个主键列,可以接受任何类型的值。您可以指定列类型。如果不指定列类型,它将从属性类型推断出来。下面的示例将创建一个带有int类型的id,您在保存之前必须手动分配其值。import { Entity, PrimaryColumn } from "typeorm"@Entity()export class User { @PrimaryColumn() id: number}@PrimaryGeneratedColumn() 创建一个主键列,其值将自动生成具有自增值的列。它将创建一个带有auto-increment/serial/sequence/identity(取决于数据库和提供的配置)的int列。在保存之前,您不必手动分配其值-值将自动生成。import { Entity, PrimaryGeneratedColumn } from "typeorm"@Entity()export class User { @PrimaryGeneratedColumn() id: number}@PrimaryGeneratedColumn("uuid") 创建一个主键列,其值将自动生成具有uuid的值。Uuid是一个唯一的字符串标识。在保存之前,您不必手动分配其值-值将自动生成。import { Entity, PrimaryGeneratedColumn } from "typeorm"@Entity()export class User { @PrimaryGeneratedColumn("uuid") id: string}

您还可以拥有复合主键列:

import { Entity, PrimaryColumn } from "typeorm"@Entity()export class User { @PrimaryColumn() firstName: string @PrimaryColumn() lastName: string}

使用save保存实体时,它始终尝试在数据库中使用给定的实体id(或ids)查找实体。 如果找到id/ids,则将更新数据库中的该行。 如果没有具有id/ids的行,将插入新行。

要通过id查找实体,可以使用manager.findOneBy或repository.findOneBy。示例:

// 使用单个主键按id查找const person = await dataSource.manager.findOneBy(Person, { id: 1 })const person = await dataSource.getRepository(Person).findOneBy({ id: 1 })// 使用复合主键按id查找const user = await dataSource.manager.findOneBy(User, { firstName: "Timber", lastName: "Saw",})const user = await dataSource.getRepository(User).findOneBy({ firstName: "Timber", lastName: "Saw",})特殊列​

有几种带有附加功能的特殊列类型:

@CreateDateColumn 是一个特殊列,它会自动设置为实体的插入日期。 您不需要设置该列-它将自动设置。

@UpdateDateColumn 是一个特殊列,每次调用实体管理器或存储库的save时,它都会自动设置为实体的更新时间。 您不需要设置该列-它将自动设置。

@DeleteDateColumn 是一个特殊列,每次调用实体管理器或存储库的软删除时,它都会自动设置为实体的删除时间。 您不需要设置该列-它将自动设置。如果设置了@DeleteDateColumn,则默认范围将是“非删除”。

@VersionColumn 是一个特殊列,每次调用实体管理器或存储库的save时,它都会自动设置为实体的版本(递增数)。 您不需要设置该列-它将自动设置。

空间列​

MS SQL、MySQL、MariaDB、PostgreSQL 和 CockroachDB 都支持空间列。TypeORM 对每个数据库的支持略有不同,特别是由于列名在不同数据库之间有所变化。

MS SQL 和 MySQL / MariaDB 的 TypeORM 支持将几何图形以 well-known text (WKT) 的形式提供和接受,因此几何列应该标记为 string 类型。

import { Entity, PrimaryColumn, Column } from "typeorm"@Entity()export class Thing { @PrimaryColumn() id: number @Column("point") point: string @Column("linestring") linestring: string}...const thing = new Thing()thing.point = "POINT(1 1)"thing.linestring = "LINESTRING(0 0,1 1,2 2)"

TypeORM 的 PostgreSQL 和 CockroachDB 支持使用 GeoJSON 作为交换格式,因此几何列应该标记为 object 或 Geometry(或其子类,如 Point),在导入 geojson 类型 后或使用 TypeORM 内置的 GeoJSON 类型。

import { Entity, PrimaryColumn, Column, Point, LineString, MultiPoint} from "typeorm"@Entity()export class Thing { @PrimaryColumn() id: number @Column("geometry") point: Point @Column("geometry") linestring: LineString @Column("geometry", { spatialFeatureType: "MultiPoint", srid: 4326, }) multiPointWithSRID: MultiPoint}...const thing = new Thing()thing.point = { type: "Point", coordinates: [116.443987, 39.920843],}thing.linestring = { type("LineString", coordinates: [ [-87.623177, 41.881832], [-90.199402, 38.627003], [-82.446732, 38.413651], [-87.623177, 41.881832], ],}thing.multiPointWithSRID = { type: "MultiPoint", coordinates: [ [100.0, 0.0], [101.0, 1.0], ],}

TypeORM试图尽力处理,但有时无法确定插入的值或PostGIS函数的结果应如何处理为几何值。因此,您可能会编写类似以下代码的代码,其中值从GeoJSON转换为PostGIS的geometry,并从json转换为GeoJSON:

import { Point } from "typeorm"const origin: Point = { type: "Point", coordinates: [0, 0],}await dataSource.manager .createQueryBuilder(Thing, "thing") // 将序列化的GeoJSON转换为具有与表规范相匹配的SRID的几何值 .where( "ST_Distance(geom, ST_SetSRID(ST_GeomFromGeoJSON(:origin), ST_SRID(geom))) > 0", ) .orderBy({ "ST_Distance(geom, ST_SetSRID(ST_GeomFromGeoJSON(:origin), ST_SRID(geom)))": { order: "ASC", }, }) .setParameters({ // 将GeoJSON转换为字符串 origin: JSON.stringify(origin), }) .getMany()await dataSource.manager .createQueryBuilder(Thing, "thing") // 将几何值结果转换为GeoJSON,以JSON格式处理(以便TypeORM知道对其进行反序列化) .select("ST_AsGeoJSON(ST_Buffer(geom, 0.1))::json geom") .from("thing") .getMany()列类型​

TypeORM支持大多数常用的数据库支持的列类型。列类型是特定于数据库类型的,这提供了更大的灵活性,使您的数据库模式看起来更加多样化。

您可以将列类型指定为@Column的第一个参数,或在@Column的列选项中指定,例如:

@Column("int")

或者

@Column({ type: "int" })

如果要指定其他类型参数,可以通过列选项来实现。例如:

@Column("varchar", { length: 200 })

或者

@Column({ type: "int", width: 200 })

关于bigint类型的注意事项:在SQL数据库中使用的bigint列类型不适合常规的number类型,而是将属性映射为string。

mysql / mariadb的列类型​

bit、int、integer、tinyint、smallint、mediumint、bigint、float、double、 double precision、dec、decimal、numeric、fixed、bool、boolean、date、datetime、 timestamp、time、year、char、nchar、national char、varchar、nvarchar、national varchar、 text、tinytext、mediumtext、blob、longtext、tinyblob、mediumblob、longblob、enum、set、 json、binary、varbinary、geometry、point、linestring、polygon、multipoint、multilinestring、multipolygon、geometrycollection、uuid、inet4、inet6

注意:UUID、INET4和INET6仅适用于mariadb以及使它们可用的相应版本。

postgres的列类型​

int、int2、int4、int8、smallint、integer、bigint、decimal、numeric、real、 float、float4、float8、double precision、money、character varying、varchar、character、 char、text、citext、hstore、bytea、bit、varbit、bit varying、timetz、timestamptz、 timestamp、timestamp without time zone、timestamp with time zone、date、time、 time without time zone、time with time zone、interval、bool、boolean、enum、point、line、 lseg、box、path、polygon、circle、cidr、inet、macaddr、tsvector、tsquery、uuid、xml、 json、jsonb、int4range、int8range、numrange、tsrange、tstzrange、daterange、geometry、 geography、cube、ltree

cockroachdb的列类型​

array、bool、boolean、bytes、bytea、blob、date、numeric、decimal、dec、float、 float4、float8、double precision、real、inet、int、integer、int2、int8、int64、 smallint、bigint、interval、string、character varying、character、char、char varying、 varchar、text、time、time without time zone、timestamp、timestamptz、timestamp without time zone、 timestamp with time zone、json、jsonb、uuid

注意:CockroachDB将所有数值数据类型都返回为string。但是,如果您省略列类型并将属性定义为number,ORM将把字符串解析为数字。

sqlite / cordova / react-native / expo的列类型​

int、int2、int8、integer、tinyint、smallint、mediumint、bigint、decimal、numeric、 float、double、real、double precision、datetime、varying character、character、 native character、varchar、nchar、nvarchar2、unsigned big int、boolean、blob、text、clob、date

mssql的列类型​

int、bigint、bit、decimal、money、numeric、smallint、smallmoney、tinyint、float、 real、date、datetime2、datetime、datetimeoffset、smalldatetime、time、char、varchar、 text、nchar、nvarchar、ntext、binary、image、varbinary、hierarchyid、sql_variant、 timestamp、uniqueidentifier、xml、geometry、geography、rowversion

oracle的列类型​

char、nchar、nvarchar2、varchar2、long、raw、long raw、number、numeric、float、dec、 decimal、integer、int、smallint、real、double precision、date、timestamp、 timestamp with time zone、timestamp with local time zone、interval year to month、 interval day to second、bfile、blob、clob、nclob、rowid、urowid

spanner的列类型​

bool、int64、float64、numeric、string、json、bytes、date、timestamp、array

enum列类型​

enum列类型由postgres和mysql支持。有多种可能的列定义方式:

使用TypeScript的枚举:

export enum UserRole { ADMIN = "admin", EDITOR = "editor", GHOST = "ghost",}@Entity()export class User { @PrimaryGeneratedColumn() id: number @Column({ type: "enum", enum: UserRole, default: UserRole.GHOST, }) role: UserRole}

注意:支持字符串、数字和混合类型的枚举。

使用包含枚举值的数组:

export type UserRoleType = "admin" | "editor" | "ghost",@Entity()export class User { @PrimaryGeneratedColumn() id: number; @Column({ type: "enum", enum: ["admin", "editor", "ghost"], default: "ghost" }) role: UserRoleType}set列类型​

set列类型由mariadb和mysql支持。有多种可能的列定义方式:

使用TypeScript的枚举:

export enum UserRole { ADMIN = "admin", EDITOR = "editor", GHOST = "ghost",}@Entity()export class User { @PrimaryGeneratedColumn() id: number @Column({ type: "set", enum: UserRole, default: [UserRole.GHOST, UserRole.EDITOR], }) roles: UserRole[]}

使用包含set值的数组:

export type UserRoleType = "admin" | "editor" | "ghost",@Entity()export class User { @PrimaryGeneratedColumn() id: number; @Column({ type: "set", enum: ["admin", "editor", "ghost"], default: ["ghost", "editor"] }) roles: UserRoleType[]}simple-array列类型​

有一种特殊的列类型称为simple-array,它可以将基本数组值存储在单个字符串列中。所有值由逗号分隔。例如:

@Entity()export class User { @PrimaryGeneratedColumn() id: number @Column("simple-array") names: string[]}const user = new User()user.names = ["Alexander", "Alex", "Sasha", "Shurik"]

将以Alexander,Alex,Sasha,Shurik的形式存储在单个数据库列中。当您从数据库加载数据时,姓名将作为姓名数组返回,就像您存储它们一样。

请注意,您在写入的值中不能有任何逗号。

simple-json列类型​

有一种特殊的列类型称为simple-json,它可以存储可以通过JSON.stringify存储在数据库中的任何值。当您没有数据库中的JSON类型并且希望存储和加载对象而无需麻烦时,这非常有用。例如:

@Entity()export class User { @PrimaryGeneratedColumn() id: number @Column("simple-json") profile: { name: string; nickname: string }}const user = new User()user.profile = { name: "John", nickname: "Malkovich" }

将以{"name":"John","nickname":"Malkovich"}的形式存储在单个数据库列中。当您从数据库加载数据时,您将通过JSON.parse获得您的对象/数组/基本值。

生成值的列​

您可以使用@Generated装饰器创建具有生成值的列。例如:

@Entity()export class User { @PrimaryColumn() id: number @Column() @Generated("uuid") uuid: string}

uuid值将自动生成并存储到数据库中。

除了"uuid"之外,还有"increment"、"identity"(仅适用于Postgres 10+)和"rowid"(仅适用于CockroachDB)生成类型,但某些数据库平台对于这种类型的生成有一些限制(例如,某些数据库只能有一个增量列,或者某些数据库要求增量是主键)。

列选项​

列选项为实体列定义了附加选项。您可以在@Column中指定列选项:

@Column({ type: "varchar", length: 150, unique: true, // ...})name: string;

ColumnOptions中可用的选项列表:

type: ColumnType - 列类型。可以是上述列类型之一。name: string - 数据库表中的列名称。默认情况下,列名称是根据属性的名称生成的。您可以通过指定自己的名称来更改它。length: number - 列类型的长度。例如,如果要创建varchar(150)类型,可以指定列类型和长度选项。width: number - 列类型的显示宽度。仅用于MySQL整数类型。onUpdate: string - ON UPDATE触发器。仅在MySQL中使用。nullable: boolean - 在数据库中将列设置为NULL或NOT NULL。默认情况下,列是nullable: false。update: boolean - 指示列值是否通过“save”操作进行更新。如果为false,您只能在首次插入对象时写入此值。默认值为true。insert: boolean - 指示列值是否在插入对象时设置。默认值为true。select: boolean - 定义在进行查询时是否默认隐藏此列。当设置为false时,标准查询将不显示列数据。默认情况下,列是select: true。default: string - 添加数据库级别的列DEFAULT值。primary: boolean - 将列标记为主键。与@PrimaryColumn使用相同。unique: boolean - 将列标记为唯一列(创建唯一约束)。comment: string - 数据库列的注释。并非所有数据库类型都支持。precision: number - 十进制(精确数值)列的精度(仅适用于十进制列),即存储的值的最大位数。用于某些列类型。scale: number - 十进制(精确数值)列的标度(仅适用于十进制列),表示小数点右侧的数字位数,不能大于精度。用于某些列类型。zerofill: boolean - 在数字列上添加ZEROFILL属性。仅适用于MySQL。如果为true,MySQL会自动将UNSIGNED属性添加到该列。unsigned: boolean - 在数字列上添加UNSIGNED属性。仅适用于MySQL。charset: string - 定义列的字符集。不适用于所有数据库类型。collation: string - 定义列的排序规则。enum: string[]|AnyEnum - 在enum列类型中用于指定允许的枚举值列表。可以指定值数组或指定枚举类。enumName: string - 定义所使用枚举的名称。asExpression: string - 生成的列表达式。仅在MySQL中使用。generatedType: "VIRTUAL"|"STORED" - 生成的列类型。仅在MySQL中使用。hstoreType: "object"|"string" - HSTORE列的返回类型。将值返回为字符串或对象。仅在Postgres中使用。array: boolean - 用于可以是数组的postgres和cockroachdb列类型(例如int[])。transformer: { from(value: DatabaseType): EntityType, to(value: EntityType): DatabaseType } - 用于将任意类型EntityType的属性转换为数据库支持的类型DatabaseType。也支持数组的转换器,写入时将按照自然顺序应用,并在读取时以相反顺序应用。例如[lowercase, encrypt]将在写入时先将字符串转换为小写,然后加密,而在读取时解密然后不进行任何操作。

注意:这些列选项大多是特定于关系数据库管理系统(RDBMS)的,不适用于MongoDB。

实体继承​

您可以通过使用实体继承来减少代码中的重复。

例如,您有Photo、Question、Post实体:

@Entity()export class Photo { @PrimaryGeneratedColumn() id: number @Column() title: string @Column() description: string @Column() size: string}@Entity()export class Question { @PrimaryGeneratedColumn() id: number @Column() title: string @Column() description: string @Column() answersCount: number}@Entity()export class Post { @PrimaryGeneratedColumn() id: number @Column() title: string @Column() description: string @Column() viewCount: number}

正如您所见,所有这些实体都有共同的列:id、title、description。为了减少重复并产生更好的抽象,我们可以为它们创建一个名为Content的基类:

export abstract class Content { @PrimaryGeneratedColumn() id: number @Column() title: string @Column() description: string}@Entity()export class Photo extends Content { @Column() size: string}@Entity()export class Question extends Content { @Column() answersCount: number}@Entity()export class Post extends Content { @Column() viewCount: number}

所有来自父实体的列(关系、嵌入等)(父实体也可以扩展其他实体)都将被继承并创建在最终实体中。

树状实体​

TypeORM支持使用邻接列表和闭包表模式存储树结构。

邻接列表​

邻接列表是一种具有自引用关系的简单模型。 这种方法的好处是简单性,缺点是由于联接限制,无法一次加载大型树结构。 示例:

import { Entity, Column, PrimaryGeneratedColumn, ManyToOne, OneToMany,} from "typeorm"@Entity()export class Category { @PrimaryGeneratedColumn() id: number @Column() name: string @Column() description: string @ManyToOne((type) => Category, (category) => category.children) parent: Category @OneToMany((type) => Category, (category) => category.parent) children: Category[]}闭包表​

闭包表在一个单独的表中以特殊的方式存储父子关系。 它在读取和写入时都非常高效。 要了解有关闭包表的更多信息,请查看Bill Karwin的精彩演示文稿。 示例:

import { Entity, Tree, Column, PrimaryGeneratedColumn, TreeChildren, TreeParent, TreeLevelColumn,} from "typeorm"@Entity()@Tree("closure-table")export class Category { @PrimaryGeneratedColumn() id: number @Column() name: string @Column() description: string @TreeChildren() children: Category[] @TreeParent() parent: Category @TreeLevelColumn() level: number}


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3