DataSource

  • 데이터베이스와 상호 작용하는 객체
    • 데이터베이스 연결 설정
    • 데이터베이스 연결 유지
    • 연결 풀 설정
  • 초기 연결/연결 풀 설정 하려면 인스턴스 초기화 메서드 호출해야 함
  • 파괴 메서드 호출될 때 연결 해제
  • 애플리케이션 부트스트랩에서 DataSource 인스턴스 초기화 메서드 호출하고 데이터 작업 완료 후 파기

 

DataSource 만들기

import { DataSource } from "typeorm"

const AppDataSource = new DataSource({
    type: "mysql",
    host: "localhost",
    port: 3306,
    username: "test",
    password: "test",
    database: "test",
})

AppDataSource.initialize()
    .then(() => {
        console.log("Data Source has been initialized!")
    })
    .catch((err) => {
        console.error("Error during Data Source initialization", err)
    })

 

DataSource 이용하기

import { AppDataSource } from "./app-data-source"
import { User } from "../entity/User"

export class UserController {
    @Get("/users")
    getAll() {
        return AppDataSource.manager.find(User)
    }
}
  • 위에서 만든 AppDataSource를 가지고 와서 사용

 

DataSource Option

  • 자주 사용하는 것들로 구성

common한 것들

  • synchronize : 모든 애플리케이션 실행 시 데이터베이스 스키마 자동 생성 여부 확인
  • supportBigNumbers
  • bigNumberStrings
  • namingStrategy : 테이블과 컬럼의 이름 형태
  • charset
  • autoLoadEntities :
  • logging
  • maxQueryExecutionTime
  • dataString

 

multiple DataSource

import { DataSource } from "typeorm"

const db1DataSource = new DataSource({
    type: "mysql",
    host: "localhost",
    port: 3306,
    username: "root",
    password: "admin",
    database: "db1",
    entities: [__dirname + "/entity/*{.js,.ts}"],
    synchronize: true,
})

const db2DataSource = new DataSource({
    type: "mysql",
    host: "localhost",
    port: 3306,
    username: "root",
    password: "admin",
    database: "db2",
    entities: [__dirname + "/entity/*{.js,.ts}"],
    synchronize: true,
})
  • config를 두 개 만들어 놓고 Entity애서 데이터 베이스를 명시하면 됨
    import { Entity, PrimaryGeneratedColumn, Column } from "typeorm"
    
    @Entity({ database: "secondDB" })
    export class User {
        @PrimaryGeneratedColumn()
        id: number
    
        @Column()
        firstName: string
    
        @Column()
        lastName: string
    }
    import { Entity, PrimaryGeneratedColumn, Column } from "typeorm"
    
    @Entity({ database: "thirdDB" })
    export class Photo {
        @PrimaryGeneratedColumn()
        id: number
    
        @Column()
        url: string
    }
    ​
     
  • 스키마가 두 개라면 Entity에서 요렇게 해주면 됨
    @Entity({ schema: "secondSchema" })
    @Entity({ schema: "thirdSchema" })

Replication

  • 읽기 전용, 쓰기 전용을 구분할 수 있음
const datasource = new DataSource({
  type: "mysql",
  logging: true,
  replication: {
    master: {
      host: "server1",
      port: 3306,
      username: "test",
      password: "test",
      database: "test"
    },
    slaves: [
      {
        host: "server2",
        port: 3306,
        username: "test",
        password: "test",
        database: "test"
      }, {
        host: "server3",
        port: 3306,
        username: "test",
        password: "test",
        database: "test"
      }
    ]
  }
});

API

  • options : dataSource 만들떄 사용하는 옵션
    const dataSourceOptions: DataSourceOptions = dataSource.options​
  • isInitialized : DataSource가 초기화되고 데이터베이스와의 초기 연결/연결 풀이 설정되었는지 여부
    const isInitialized: boolean = dataSource.isInitialized
  • driver : 데이터소스의 원본이 되는 데이터베이스의 드라이버
    const driver: Driver = dataSource.drive
  • manager : 엔터티 매니저. 엔터티와 작업할 때 사용
    const manager: EntityManager = dataSource.manager
    // you can call manager methods, for example find:
    const users = await manager.find()
  • initialize : 데이터소스를 초기화하고, 커넥션 풀을 open
    await dataSource.initialize()
  • destroy : 데이터 소스를 닫고 파괴함 (모든 연결 닫음) 어플리케이션이 셧다운 될 때 이 메서드를 불러야 함
    await dataSource.destroy()
  • synchronixe : 데이터베이스 스키마 동기화.
    • synchronize: true ← 옵션이 이렇게 되어 있으면 이 것을 호출함
    • 어플리케이션 시작할 때 이 메서드를 호출해서 사용하기도
    await dataSource.synchronize()
    
  • dropDatabase : 데이터베이스 드롭하고 모든 데이터를 드롭. 조심해서 사용
    await dataSource.dropDatabase()
  • runMigration : 보류 중인 모든 마이그레이션을 실행
    await dataSource.runMigrations()
  • hasMetadata : 주어진 엔티티에 대한 메타데이터가 등록되었는지 확인
    if (dataSource.hasMetadata(User))
        const userMetadata = dataSource.getMetadata(User)
  • getMetadata : 주어진 엔터티의 엔터티 메타데이터를 받아옴.
    • 테이블 이름을 지정할 수도 있으며, 해당 테이블 이름을 가진 엔티티 메타데이터가 발견되면 반환
    const userMetadata = dataSource.getMetadata(User)
    // now you can get any information about User entity
    
  • getRepository : 지정된 엔티티의 리포지토리를 가져옴
    • 테이블 이름을 지정할 수도 있으며, 해당 테이블의 리포지토리가 발견되면 반환
    const repository = dataSource.getRepository(User)
    // now you can call repository methods, for example find:
    const users = await repository.find()
    
  • getTreeRepository : 지정된 트리 엔터티의 리포지토리 가져옴
    • 위와 동
    const repository = dataSource.getTreeRepository(Category)
    // now you can call tree repository methods, for example findTrees:
    const categories = await repository.findTrees()
    
  • transaction : 단일 데이터베이스 트랜잭션에서 여러 데이터베이스 요청이 실행되는 단일 트랜잭션을 제공
    	await dataSource.transaction(async (manager) => {
        // NOTE: you must perform all database operations using given manager instance
        // its a special instance of EntityManager working with this transaction
        // and don't forget to await things here
    })
  • query : raq Sql Query를 실행
    const rawData = await dataSource.query(`SELECT * FROM USERS`)
    
    // You can also use parameters to avoid SQL injection
    // The syntax differs between the drivers
    
    // aurora-mysql, better-sqlite3, capacitor, cordova, 
    // expo, mariadb, mysql, nativescript, react-native, 
    // sap, sqlite, sqljs
    const rawData = await dataSource.query(
        'SELECT * FROM USERS WHERE name = ? and age = ?',
        [ 'John', 24 ]
    )
    
    // aurora-postgres, cockroachdb, postgres
    const rawData = await dataSource.query(
        'SELECT * FROM USERS WHERE name = $1 and age = $2',
        ['John', 24]
    )
    
    // oracle
    const rawData = await dataSource.query(
        'SELECT * FROM USERS WHERE name = :1 and age = :2',
        ['John', 24]
    )
    
    // spanner
    const rawData = await dataSource.query(
        'SELECT * FROM USERS WHERE name = @param0 and age = @param1',
        [ 'John', 24 ]
    )
    
    // mssql
    const rawData = await dataSource.query(
        'SELECT * FROM USERS WHERE name = @0 and age = @1',
        [ 'John', 24 ]
    )
  • createQueryBuilder : 쿼리를 빌드하는 데 사용할 수 있는 쿼리 빌더 생성
    const users = await dataSource
      .createQueryBuilder()
      .select()
      .from(User, "user")
      .where("user.name = :name", { name: "John" })
      .getMany()
  • createQueryRunner : 단일 실제 데이터베이스 dataSource를 관리하고 작업하는 데 사용되는 쿼리 실행기 생성
    • 우리 팀에서는 이 걸로 transactional 처리
    const queryRunner = dataSource.createQueryRunner()
    
    // you can use its methods only after you call connect
    // which performs real database connection
    await queryRunner.connect()
    
    // .. now you can work with query runner and call its methods
    
    // very important - don't forget to release query runner once you finished working with it
    await queryRunner.release()
    

 

 

 

 

 

 

 

 

 

 

 

 

+ Recent posts