[TypeScript][PostgreSQL][TSyringe][Express]TypeORM 2 사용해보기
39604 단어 tsyringetypescriptexpresstypeorm
소개
이번에는 TypeORM을 이용하여 관계를 해보도록 하겠습니다.
환경
외래 키
아래와 같이 외래 키를 추가할 수 있습니다.
author.ts
import {Entity, PrimaryGeneratedColumn, Column} from "typeorm";
@Entity('author')
export class Author {
@PrimaryGeneratedColumn()
id: number = -1;
@Column({
name: 'name',
type: 'text',
nullable: false
})
name: string = '';
}
장르.ts
import {Entity, PrimaryGeneratedColumn, Column} from "typeorm";
@Entity('genre')
export class Genre {
@PrimaryGeneratedColumn()
id: number = -1;
@Column({
name: 'name',
type: 'text',
nullable: false
})
name: string = '';
}
book.ts
import {Entity, PrimaryGeneratedColumn, Column, ManyToOne, JoinColumn} from "typeorm";
import { Author } from "./author";
import { Genre } from "./genre";
@Entity('book')
export class Book {
@PrimaryGeneratedColumn()
id: number = -1;
@Column({
name: 'name',
type: 'text',
nullable: false
})
name: string = '';
@ManyToOne(type => Author)
@JoinColumn({ name: 'authorId', referencedColumnName: 'id' })
author: Author = new Author();
@ManyToOne(type => Genre)
@JoinColumn({ name: 'genreId', referencedColumnName: 'id' })
genre: Genre = new Genre();
@Column({
name: 'last_update_date',
nullable: false,
type: 'timestamp with time zone'
})
lastUpdateDate: Date = new Date();
}
null 제약이 아님
한 가지 문제는 "authorId"및 "genreId"에 not null 제약 조건을 추가할 수 없다는 것입니다.
그래서 속성을 명시적으로 추가합니다.
book.ts
...
export class Book {
...
@Column({
name: 'authorId',
type: 'integer',
nullable: false
})
authorId: number = 0;
@ManyToOne(type => Author)
@JoinColumn({ name: 'authorId', referencedColumnName: 'id' })
author: Author = new Author();
@Column({
name: 'genreId',
type: 'integer',
nullable: false
})
genreId: number = 0;
@ManyToOne(type => Genre)
@JoinColumn({ name: 'genreId', referencedColumnName: 'id' })
genre: Genre = new Genre();
...
}
이제 아래와 같이 행을 추가할 수 있습니다.
dataContext.ts
import "reflect-metadata";
import { singleton } from "tsyringe";
import { Connection, createConnection } from "typeorm";
// I must not connect two or more times.
@singleton()
export class DataContext {
private connection: Connection|null = null;
public async getConnection(): Promise<Connection> {
if(this.connection != null) {
return this.connection;
}
this.connection = await createConnection();
return this.connection;
}
}
bookService.ts
import { autoInjectable } from "tsyringe";
import { Connection, QueryRunner } from "typeorm";
import { DataContext } from "../data/dataContext";
import { Author } from "../entities/author";
import { Book } from "../entities/book";
import { Genre } from "../entities/genre";
@autoInjectable()
export class BookService {
public constructor(private context: DataContext) {
}
public async createSeedData() {
const connection = await this.context.getConnection();
const queryRunner = connection.createQueryRunner();
await queryRunner.startTransaction();
try {
const authors = await this.createAuthors(connection, queryRunner);
const genres = await this.createGenres(connection, queryRunner);
const result = await this.createBooks(connection, queryRunner, authors, genres);
if(result === true) {
await queryRunner.commitTransaction();
}
} catch (err) {
console.error(err);
await queryRunner.rollbackTransaction();
}
}
private async createAuthors(connection: Connection, queryRunner: QueryRunner): Promise<readonly Author[]> {
const items = await connection.getRepository(Author)
.createQueryBuilder('author')
.getMany();
if(items.length > 0) {
return items;
}
const newItem = new Author();
newItem.name = 'David Flanagan';
await queryRunner.manager.save(newItem);
return [newItem];
}
private async createGenres(connection: Connection, queryRunner: QueryRunner): Promise<readonly Genre[]> {
const items = await connection.getRepository(Genre)
.createQueryBuilder('genre')
.getMany();
if(items.length > 0) {
return items;
}
const programming = new Genre();
programming.name = 'Programming';
await queryRunner.manager.save(programming);
const manga = new Genre();
manga.name = 'Manga';
await queryRunner.manager.save(manga);
const cooking = new Genre();
cooking.name = 'Cooking';
await queryRunner.manager.save(cooking);
return [programming, manga, cooking];
}
private async createBooks(connection: Connection, queryRunner: QueryRunner,
authors: readonly Author[], genres: readonly Genre[]): Promise<boolean> {
const items = await connection.getRepository(Book)
.createQueryBuilder('book')
.getMany();
if(items.length > 0) {
return false;
}
const author = authors[0];
const genre = genres.find(g => g.name === 'Programming');
const newItem = new Book();
newItem.name = 'Javascript: The Definitive Guide';
newItem.price = 6318;
newItem.author = author;
newItem.genre = genre ?? genres[0];
await queryRunner.manager.save(newItem);
return true;
}
}
내부 조인
Entity Framework Core에서 "Book"데이터를 가져올 때 외래 키로 "Genre"및 "Author"인스턴스를 설정할 수 있습니다.
var books = await context.Books
.Include(b => b.Genre)
.Include(b => b.Author)
.ToListAsync();
TypeORM은 어떻습니까?
자동으로 설정되지 않기 때문에 "innerJoinAndSelect"를 사용합니다.
bookService.ts
...
export class BookService {
...
public async getBooks(): Promise<readonly Book[]> {
const connection = await this.context.getConnection();
return await connection.getRepository(Book)
.createQueryBuilder('book')
.innerJoinAndSelect('book.genre', 'genre')
.innerJoinAndSelect('book.author', 'author')
.getMany();
}
...
}
index.ts
import "reflect-metadata";
import express from 'express';
import { container } from 'tsyringe';
import { BookService } from "./books/bookService";
const port = 3000;
const app = express();
app.use(express.json());
app.use(express.raw());
app.use(express.static('clients/public'));
app.get('/books', async (req, res) => {
const books = container.resolve(BookService);
res.json(await books.getBooks());
});
app.listen(port, () => {
console.log(`Example app listening at http://localhost:${port}`)
});
결과
TypeORM의 통화 유형?
"책"테이블에 "가격"열을 추가하고 싶습니다.
하지만 어떤 유형을 사용해야 합니까?
C#에서는 보통 "decimal"을 사용합니다.
그러나 JavaScript 및 TypeScript에는 유형이 없습니다.
그리고 "BigInt"는 정수만 처리할 수 있습니다.
Dinero.js 과 같은 통화 유형을 처리하기 위한 일부 라이브러리가 있습니다.
그러나 그들은 JavaScript|TypeScript 세계에서만 사용하기 위한 것입니다.
결국 "숫자"유형을 사용하기로 결정했습니다.
book.ts
export class Book {
...
@Column({
name: 'price',
type: 'money',
nullable: false
})
price: number = 0;
}
Reference
이 문제에 관하여([TypeScript][PostgreSQL][TSyringe][Express]TypeORM 2 사용해보기), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/masanori_msl/typescript-postgresql-tsyringe-express-try-typeorm-2-3bka텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)