1. Pick을 활용한 필드 선택
import { EntityTarget, getRepository } from 'typeorm';
async function selectFields<T, K extends keyof T>(entity: EntityTarget<T>, fields: K[]): Promise<Pick<T, K>[]> {
const repository = getRepository(entity);
return repository
.createQueryBuilder()
.select(fields.map(field => `${entity.name}.${field}`))
.getMany() as Promise<Pick<T, K>[]>;
}
const users = await selectFields(User, ['id', 'name']);
2. 조건 배열을 활용한 유연한 TypeORM 쿼리 생성
import { EntityTarget, getRepository, SelectQueryBuilder } from 'typeorm';
interface QueryCondition<T> {
fieldName: EntityFieldNames<T>;
value: any;
operator?: '=' | '>' | '<' | 'LIKE';
}
async function queryWithConditions<T>(
entity: EntityTarget<T>,
conditions: QueryCondition<T>[]
): Promise<T[]> {
const repository = getRepository(entity);
let queryBuilder = repository.createQueryBuilder('entity');
conditions.forEach(({ fieldName, value, operator = '=' }) => {
queryBuilder = queryBuilder.andWhere(`entity.${fieldName} ${operator} :value`, { value });
});
return queryBuilder.getMany();
}
async function fetchUsers() {
const users = await queryWithConditions(User, [
{ fieldName: 'name', value: 'John Doe' },
{ fieldName: 'age', value: 30, operator: '>' }
]);
return users;
}
3. 유연한 쿼리 빌더
import { EntityTarget, getRepository, SelectQueryBuilder } from 'typeorm';
interface QueryOptions<T> {
select?: (keyof T)[];
where?: Partial<Record<keyof T, any>>;
orderBy?: Array<{ field: keyof T; order: 'ASC' | 'DESC' }>;
}
function buildDynamicQuery<T>(entity: EntityTarget<T>, options: QueryOptions<T>): SelectQueryBuilder<T> {
const repository = getRepository(entity);
const queryBuilder = repository.createQueryBuilder(entity.name.toLowerCase());
if (options.select && options.select.length > 0) {
queryBuilder.select(options.select.map(field => `${entity.name.toLowerCase()}.${String(field)}`));
}
if (options.where) {
Object.entries(options.where).forEach(([field, value]) => {
queryBuilder.andWhere(`${entity.name.toLowerCase()}.${field} = :value`, { value });
});
}
if (options.orderBy && options.orderBy.length > 0) {
options.orderBy.forEach(order => {
queryBuilder.addOrderBy(`${entity.name.toLowerCase()}.${String(order.field)}`, order.order);
});
}
return queryBuilder;
}
async function fetchUsersWithDynamicQuery() {
const userQuery = buildDynamicQuery(User, {
select: ['id', 'name'],
where: { isActive: true, age: 30 },
orderBy: [{ field: 'name', order: 'ASC' }],
});
const users = await userQuery.getMany();
return users;
}