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()