- Published on
typeorm entities 에 대해서
- Authors
- Name
- 길재훈
typeorm entities 에 대해서 알아본다.
Typeorm 의 Docs 를 읽어보면서, 감탄이 나오는 부분이 바로 이 Entities 이다.
Entity 는 database table 및 collection 에 mapping 된 class 이다.
Entities 를 사용하는데 있어서, Decorator 를 사용하는데,
매우 간편하게 만들어진다.
import { Entity, PrimaryGeneratedColumn, Column } from 'typeorm'
@Entity()
export class User {
@PrimaryGeneratedColumn()
id: number
@Column()
name: string
@Column()
isActive: boolean
}
매우 간편하게 만들어진다. 이렇게 만들어진 table 은 다음과 같다.
+-------------+--------------+----------------------------+
| user |
+-------------+--------------+----------------------------+
| id | int(11) | PRIMARY KEY AUTO_INCREMENT |
| name | varchar(255) | |
| isActive | boolean | |
+-------------+--------------+----------------------------+
대단하지 않는가? 매우 명시적으로 code 작성이 가능하다.
이전의 Sequelize 를 잠깐 공부하고 있었는데, 보다 더 나은 방식으로 느껴진다.
여기서 Entity 를 사용하고 싶다면 앞전의 Data source 에 대해서 의 entities options 를 사용하여 등록해주어야 한다.
import { DataSource } from "typeorm"
const dataSource = new DataSource({
type: "mariadb",
host: "localhost",
port: 3306,
username: "test",
password: "test",
database: "test",
entities: ["entity/*.js"], // <-- entity directory 의 경로
})
또한 보통 Prefix 를 사용하여 지정도 하니, prefix option 사용도 고려하는것이 좋을것 같다.
추가적으로,
Docs에서는constructor arguments사용은 선택적이라고 말한다.그 이유로는,
database를 로딩할때entity class의instance를 생성함으로 생성자 인수를 인식하지 못한다고 말한다.이부분은 내부동작에 대한 원리를 아직은 모르므로,
Docs를 읽으면서 더 자세히 보아야 겠다.
Entity Columns
DB 상의 Columns 를 뜻한다.
TypeORM 의 각 Entity class property 들은 @Column 을 사용하여 table column 과 mapping 하도록 한다.
이러한 Columns 들은 여러종류가 있는데 각 종류에 대해서 보도록 한다.
@PrimaryColumn
Entity 는 반드시 하나의 Primary key 을 갖는다. 이러한 Primary key 를 가진 Column 을 설정하는 Decorator 이다.
import { Entity, PrimaryColumn } from "typeorm"
@Entity()
export class User {
@PrimaryColumn()
id: number
}
``Object.openSync (node:fs:601:3)
12:03:49.278 at Object.readFileSync (node:fs:469:35)
12:03:49.278
> 보통 `modeling` 시 어떠한 `table` 에 종속된 `column` 이 있을때 정규화시켜, `parent table id` 와 `child table id` 를 합쳐서 `primary key` 로 만들기도 한다.
```ts
import { Entity, PrimaryColumn } from "typeorm"
@Entity()
export class User {
@PrimaryColumn()
firstName: string
@PrimaryColumn()
lastName: string
}
단순하게 이렇게, @PrimaryColumn 을 2개 만들어주면 된다.
이제 id 는 primary key 를 가진 id 가 된다.
@PrimaryGeneratedColumn
Primary key 생성은 알겠다.
하지만 보통은 Primary key 를 Int 형식으로 만들고,AUTO_INCREMENT 형식으로 자동 증분 되도록 생성하기도 한다.
이러한 기능을 넣어 만든 decorator 가 @PrimaryGeneratedColumn 이다.
import { Entity, PrimaryGeneratedColumn } from "typeorm"
@Entity()
export class User {
@PrimaryGeneratedColumn()
id: number
}
이제 id 는 자동증분되는 primary key 이다.
@PrimaryGeneratedColumn("uuid")
Primary key 를 AUTO_INCREMENT 방식으로 생성하기도 하지만, 이는 단순히 1 부터 값이 증가하는 방식으로 구성된다.
이렇게 만들지 않고, 특별한 중복되지 않는 key 를 사용하여 만들수 있는데 그것이 uuid 이다.
uuid 는 중복되지 않는 key 이므로, primary key 로 작성 가능하다.
uuid 로 작성하고 싶다면, @PrimaryGeneratedColumn 의 인자로 uuid 문자열을 넣어주면 된다.
import { Entity, PrimaryGeneratedColumn } from "typeorm"
@Entity()
export class User {
@PrimaryGeneratedColumn("uuid")
id: string
}
@CreateDateColumn
생성시 자동적으로 time 을 추가해주는 Decorator 이다.
@Entity()
export class User {
@CreateDateColumn()
createdDate: Date
}
@CreateDateColumn
Entity 를 Save 할때마다, 해당 Column 의 time 을
업데이트 해주는 Column 이다.
@Entity()
export class User {
@UpdateDateColumn()
updatedDate: Date
}
@DeleteDateColumn
Sofe-delete 시에 Delete 된 time 을 자동적으로 설정 해주는 Column 이다.
만약, @DelateDateColumn 이 설정되어 있다면, TypeORM 의 기본 scope 는 non-delete 가 될것이라고 한다.
@Entity()
export class User {
@DeleteDateColumn()
deletedDate: Date
}
@VersionColumn
자동적으로 Versioning 해주는 Column 이다. 여기서는 숫자를 증분해주어서 자동적으로 설정해주는듯 하다.
자동적으로 증분되는 조건은 save 가 호출될때, 마다 설정해준다.
@Entity()
export class User {
@VersionColumn()
version: number
}
Spatial Columns
거의 왠만한 RDBMS 들은 spatial columns 를 지원한다. TypeORM 역시 이러한 부분을 제공해주는듯 하다.
MySQL/MariaDB 는 geometires 로 WKT(Well-Known Text) 를 제공한다고 한다.
그래서 Geometry Columns 는 String 타입과 함께 tagged 된다.
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)"
반면, PostgreSQL and CockroachDB 같은경우는 GeoJSON 포멧으로 변환되므로, Object 또는 Geometry(or subclasses, eg Point) 방식으로 제공된다고 한다.
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],
],
}
이 부분은 Geometry 관련해서, data 저장시 다시 살펴보도록 한다.
Column Types
지금까지 Column 의 종류를 보았고,Column 에 사용될 Data Type 에 대해서 살펴본다.
Colume Types 를 지정하기 위해서는 Column Decorator 에
인자로 Type 을 문자열로 넣어준다.
@Column("int")
// or
@Column({ type: "int" })
// or
@Column("varchar", { length: 200 })
// or
@Column({ type: "int", width: 200 })
이러한 Type 이 존재하지만, 이는 DB 의 종류에 따라
그 Type 이 달라지기도 한다.
이부분에 대해서는 Column types for mysql/mariadb 에서 보도록 한다.
enum Column Type
mysql 과 postgres 에서는 emnum 타입을 지원한다. 이를 사용하기 위해서는 다음과 같은 문법을 사용한다.
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
}
Column 은 총 3가지 타입을 지원해주며, 이는 다음과 같다.
type:
Column의 타입 지정enum:
enum으로 선언된 변수를 넣어준다.default:
enum으로 넣어준 변수에서default로 사용될 값을 지정한다.
또는, enum option 에 배열을 넣어주어서 사용도 가능하다.
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 Column Type
mariadb 는 set 타입역시 지원한다.
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[]
}
이 역시, enum 을 Array 로 받아서 처리가능하다.
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 Column type
TypeORM 은 simple-array 라는 특별한 Column 을 지원한다.
이는 Array 인듯 하지만, 실제로 저장되는 데이터는 Comma 를 가진 문자열로 저장된다.
정규형 공부할때 보는,
Comma로 이어진다가속성처럼 생겼다.
이를 이해하기 위해 다음을 보도록 하자.
@Entity()
export class User {
@PrimaryGeneratedColumn()
id: number
@Column("simple-array")
names: string[]
}
위의 예시에서 보면 names 는 string[] 타입이며,Column 은 simple-array 이다.
만약 이러한 names 에 배열을 집어 넣어보자.
const user = new User()
user.names = ["Alexander", "Alex", "Sasha", "Shurik"]
이때, 저장되는 데이터는 다음처럼 저장된다.
Alexander,Alex,Sasha,Shurik
names 컬럼에 들어가는 값이 마치 다가속성처럼 저장되는 것이다.
이러한 부분을 많이 사용하는지는 아직 미지수이다. 하지만, Programing 입장에서 보면, 배열값이 한정적으로 사용된다면, 괜찮은 방식일수 있겠다는 생각도 같이 든다.
주의사항
작성하는 값에
Comma가 없어야 제대로 동작한다.
simple-json Column type
simple-array 타입도 보았는데, json 이 있다고 해도 별로 놀랍지는 않다.
이는 DB 에 JSON.stringify 로 저장되게 할 수 있다. 즉, 문자열로 저장된다는 것이다.
생각해보면 꽤나 간단하게 구현가능할것 같기도 하다. 머리를 잘썼다.
@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"}"
이제 DB 로 부터 해당 값을 가져온다면, JSON.parse 를 통해서
그 값은 Object/array/primitive 값으로 받게 될것이다.
Columns with generated values
@Generated 데커레이터가 존재하는데, 이 데커레이터는 생성된 값으로 해당 열에 자동적으로 값 주입이 가능하다.
@Entity()
export class User {
@PrimaryColumn()
id: number
@Column()
@Generated("uuid")
uuid: string
}
이제 uuid 컬럼은 자동적으로 생성된 uuid 값을 가진다.
이 외에도 increment, identity(postgres), rowid(cockroachDB) 를 줄수 있는데,
이러한 유형으로 만들어진 이유는 각 DB 마다 지원하는 generated 타입이 다르기 때문이다.
Column options
이렇게 Column Types 를 보았으니, Column options 를 보도록 한다.
type: ColumnType
Column에 사용될 타입을 지정한다.name: string
DB Table에Column의 이름을 지정한다.length: number
Column Type의length값을 지정한다.
만약,varchar타입에200의length값을 지정하고 싶다면@Column({type: 'varchar', length: 200})으로 지정가능하다.width: number
Column타입의width를 표시한다.
이는number타입에 해당하는 것으로, 허용 가능한 값의 범위를 뜻하는듯 하다.
오직 MySQL integer types 를 위해 사용된다고 한다.
이부분은 명확하게 맞는지 모르겠다. 다른
SQL들도 값의 범위가 있을텐데?
onUpdate: string
이는Constraint의ON UPDATE를trigger한다.nullable: boolean
True이면Null을 허용하지만,False이면NOT NULL로 허용하지 않는다.default로nullable: false이다.update: boolean
save작업에 의해update되는지 허용 여부를 결정한다.
만약false라면object에 처음insert될때만 쓰기 가능하다. (즉,update가 안되다는 말이다...)Default값은True이다.insert: boolean
Object에 처음insert될때,Column값이 설정되어 있는지 여부를 알려준다.Default값은True이다.select: boolean
query를 만들때, 기본적으로 이Column을 숨길지 아닐지 결정한다.false로 설정될떼, 이Column data가 표준 쿼리와 함께 표시되지 않을 것이다.Default로select: true이다.default: string
Default값을 할당한다.primary: boolean
Primary로 표시한다.
이는@PrimaryColumn과 같다.unique: boolean
Column을unique한 값으로 만든다.comment: string
Column의 설명을 달 수 있다.
모든 데이터베이스에서 지원하는 부분은 아니라고 한다.precision: number
deciaml의 정밀도를 지정한다.zerofill: boolean
숫자 컬럼에ZEROFILL속성을 넣는다.
이는MySQL에서 사용가능하며,true이면,UNSIGNED속성의 컬럼이 되며 자동적으로 추가된다.unsigned: boolean
UNSIGNED속성이 추가되며 숫자 컬럼이 부호없는 숫자가 된다.charset: string
원하는Character set지정이 가능하다.
모든DB타입에서 지원하지는 않는다고 말한다.collation: string
Column의collation을 지정한다.enum: string[] | AnyEnum
enum컬럼의 타입을 지정할때 사용된다.
지정한enum혹은 값의array를 지정할 수 있다.enumName: string
enum을 사용한다면 그 이름을 지정한다.asExpression: string
Generated column expression방식이라는데, 해당 문법은 현재 나도 생소해서 추가적으로MYSQL을 보고 공부한후 이해해야할 것 같다.generatedType: "VIRTUAL" | "STORED"
Generated column type이라는데, 이부분역시 생소하다.hstoreType: "object"|"string"
Postgres에서 사용하는Type인HSTORE컬럼을 사용한다고 한다.array: boolean
Postgres및CockroachDB의array컬럼타입을 사용한다.transformer
임의의EntityType속성을DB에서 지원하는DB Type유형으로 변환하는데 사용한다고 한다.
(여기서 이를marshal이라고 표현하는데, 이 뜻이 변환을 말하는것 같다.. )
이부분은 조금 더 살펴보아야 겠다.
다른 유용한 방식으로 사용하는 것 같기도 하고 애매하다..
Entity inheritance
Entity 는 Class 이다. 즉, 상속 가능하다!!
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
}
Tree entities
TypeORM 은 Adjacency list 및 Closure table 을 tree structure 저장 패턴으로 지원한다.
Tree entities에 대해서는 기본적인 개념을 알고 보아야 할것같다. 이부분에 대해서는 추가적인 내용으로 공부내용을 작성할 생각이다.
Adjacency list
Adjacency list(인접 목록) 은 그냥 자체 참조가 가능한 모델이다.
이 방식은 단순하지만, Join limiations 로 인해 Big tree 를 한번에 load 하지 못하는 것이 단점이라고 설명하고 있다.
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[]
}
Closure table
Closure table 은 기존의 자기참조 relationship 에 대한
대책으로써 만들어진 table 방법이다.
이는 기존의 자손과 조상이라는 개념을 사용하여, 가장 상단의 Table 부터 아래 마지막 자손 Table 까지의 관계도를 Table 로 만들어, 원하는 Column 을 더 효율적으로 검색하기 위한 방법이다.
이러한 방식을 지원하기 위해 TypeORM 은 다음처럼 작성하기를 원한다.
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
}
여기서 level 은 Closure Table 의 Depth 를 말하는 듯 하다.
이 부분에 대한 개념정도는 이해한 부분으로, 이 Logic 이 어떻게 이루어져 있을지 머릿속으로 잘 그려지지는 않는다.
일단, 이러한 부분을 제공하며 사용할 수 있다는 정도로 넘어가고, 더 자세한 부분은 SQL 방법론들을 보면서 익히도록 하는것이 좋을 듯 싶다.
Embedded Entities
TypeORM 은 Class inheritance 뿐만 아니라,Enitity 를 내장할 수 있는 방법역시 제공한다.
다음을 보자.
import { Column } from "typeorm"
export class Name {
@Column()
first: string
@Column()
last: string
}
위는 Name 이라는 Column 으로 이루어진 Class 이다.
중요한건 Entity 데커레이터를 사용하지 않았다는 점이다.
이는 Embedded Column 으로 사용하기 위한 초석이다.
import { Entity, PrimaryGeneratedColumn, Column } from "typeorm"
import { Name } from "./Name"
@Entity()
export class User {
@PrimaryGeneratedColumn()
id: string
@Column(() => Name)
name: Name
@Column()
isActive: boolean
}
보았는가? 위는 Name 클래스를 가져온후, Column 데커레이터에 함수로 Name 을 전달하여, name 컴럼을 만들었다.
이때, TypeORM 은 colums 를 connect 할 수 있다고 표현한다.
이제 해당 Colume 을 Table 로 만들어 보면 다음처럼 이루어져 있다.
+-------------+--------------+----------------------------+
| user |
+-------------+--------------+----------------------------+
| id | int(11) | PRIMARY KEY AUTO_INCREMENT |
| nameFirst | varchar(255) | |
| nameLast | varchar(255) | |
| isActive | boolean | |
+-------------+--------------+----------------------------+
이는 마치 컴포넌트를 재사용하는 방식처럼 자주 사용되는 Column 을 만들어 사용하기 용이한듯 싶다.
Concrete Table inheritance(구상 테이블 상속)
코드의 중복을 줄이는데 상속 만큼 좋은것은 없다.
다음을 보자.
@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 이 중복됨을 보인다. 앞에서는 Embedded Column 을 사용하여 중복됨을 피했지만,
abstract class 를 사용하여, 중복되는 구체적 로직들을 상속하여 처리 가능하다.
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
}
부모로 부터 상속받아, Entity 로 만든다.
Single Table inheritance
TypeORM 은 Concrete Table 이 아닌, Single Table 로 부터의 상속도 지원한다.
이때 중요한 부분은 @TableInheritance 데커레이터를 사용하여, 상속을 받을 Single Table 을 선언하고, 이후 @childEntity 를 사용하여 Single Table 의 자식으로 들어갈 Class 를 만든다.
@Entity()
@TableInheritance({ column: { type: "varchar", name: "type" } })
export class Content {
@PrimaryGeneratedColumn()
id: number
@Column()
title: string
@Column()
description: string
}
@ChildEntity()
export class Photo extends Content {
@Column()
size: string
}
@ChildEntity()
export class Question extends Content {
@Column()
answersCount: number
}
@ChildEntity()
export class Post extends Content {
@Column()
viewCount: number
}
이제 photos, questions, posts 는 contents 테이블안에 save 된다.
보면서 아래의 구문이 약간은 이상하게 보인다..
@TableInheritance({ column: { type: "varchar", name: "type" } })
하지만, 잘 생각해보면, 상속받을 column 의 타입이 varchar 이며 이름은 type 을 가지면, 상속받을 수 있도록 지정한것으로 보인다.
그러므로 모든 @Column 은 내부적으로 type 을 가지므로,
모든 Column 을 상속받는다는 뜻으로 이해하고 있다.
View Entity
Database View 를 mapping 한 Class 이다. 이를 위해서 @ViewEntity 데커레이터를 사용하면 쉼게 새로운 Class 를 정의할 수 있다.
@ViewEntity 는 몇가지 옵션들이 존재하는데 다음과 같다.
name
view의 이름이다.
이름을 지정하지 않는다면entity class name으로 생성된다.database
DB server안의database이름이다.schema
Schema이름이다.expression
view를 정의할 표현식이다.
이는 반드시 정의되어야한다.dependsOn
현재view가 의존하는 다른view들의list를 말한다.
만약view에 정의된것이 다른view를 사용한다면,
올바르게migration될 수 있도록 올바른 순서로 정의해야 한다.
위의 expression 은 다음처럼 작성할 수 있다.
@ViewEntity({
expression: `
SELECT "post"."id" AS "id", "post"."name" AS "name", "category"."name" AS "categoryName"
FROM "post" "post"
LEFT JOIN "category" "category" ON "post"."categoryId" = "category"."id"
`
})
또는 QueryBuilder 를 사용하여 정의가능하다.
@ViewEntity({
expression: (dataSource: DataSource) => dataSource
.createQueryBuilder()
.select("post.id", "id")
.addSelect("post.name", "name")
.addSelect("category.name", "categoryName")
.from(Post, "post")
.leftJoin(Category, "category", "category.id = post.categoryId")
})
이렇게 생성된 view 는 DataSource 의 entities 배열에 등록되어야 한다.
import { DataSource } from "typeorm"
import { UserView } from "./entity/UserView"
const dataSource = new DataSource({
type: "mysql",
host: "localhost",
port: 3306,
username: "test",
password: "test",
database: "test",
entities: [UserView],
})
자, 이제 해당 @ViewEntity 를 사용할 Class 를 보도록 하자.
import { ViewEntity, ViewColumn } from "typeorm"
@ViewEntity({
expression: `
SELECT "post"."id" AS "id", "post"."name" AS "name", "category"."name" AS "categoryName"
FROM "post" "post"
LEFT JOIN "category" "category" ON "post"."categoryId" = "category"."id"
`,
})
export class PostCategory {
@ViewColumn()
id: number
@ViewColumn()
name: string
@ViewColumn()
categoryName: string
}
위는 @ViewEntity 에서 정의한 expression 에 따라,@ViewColumn 데커레이터를 사용한것을 볼 수 있다.
QueryBuilder 를 사용한 @ViewEntity 는 다음과 같다.
import { ViewEntity, ViewColumn } from "typeorm"
@ViewEntity({
expression: (dataSource: DataSource) =>
dataSource
.createQueryBuilder()
.select("post.id", "id")
.addSelect("post.name", "name")
.addSelect("category.name", "categoryName")
.from(Post, "post")
.leftJoin(Category, "category", "category.id = post.categoryId"),
})
export class PostCategory {
@ViewColumn()
id: number
@ViewColumn()
name: string
@ViewColumn()
categoryName: string
}
View Column options
@ViewColomn 에도 여러 옵션들이 존재한다.
name: string
Column이름을 지정한다.transformer
지원가능한Type으로 변경해주는 변경자인듯 한데,
이부분은 잘 와닫지 않아서 추후 더 살펴볼 예정이다.
Seperating Entity Definition
해당 부분은 Sequelize 의 define 처럼 사용가능하도록
만든 문법 같은데 많이 사용하지는 않을 것 같아서,
내용을 정리하지는 않는다.
혹시몰라 Seperating Entity Definition 여기세서 볼 수 있도록 링크는 남기도록 한다.
마무리
확실히 API 가 참 많기도 하며, 기본적인 개념이 밑바탕이 되어야 이해가 갈만한 내용이 많다.
특히 Tree Entities 부분은, 기본적인 개념을 밑바탕이 있어야
이해가 수월할 듯 싶다.
다음은, Relations 관련 내용을 정리하도록 한다.
오늘내로 내용 정리이후에, API 코드 작성을 목표로 하고 있는데, 아직 이해해야할 부분이 많으므로 최대한 목표로 삼은 부분까지 공부하도록 할것이다.