Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TypeORM의 Repository Pattern과 QueryBuilder Pattern #41

Open
rimo030 opened this issue Nov 14, 2023 · 2 comments
Open

TypeORM의 Repository Pattern과 QueryBuilder Pattern #41

rimo030 opened this issue Nov 14, 2023 · 2 comments
Assignees
Labels
NestJS NestJS and its associated libraries

Comments

@rimo030
Copy link
Owner

rimo030 commented Nov 14, 2023

📕Repository Pattern

Repository는 Entity에 대한 CRUD를 관리한다.
의존성 주입을 위해 @InjectRepository() 를 사용한다.

Repository API

위 공식문서에서 기본적인 CRUD 서비스 내용을 긁어왔다.

create

  • Creates a new instance of User. Optionally accepts an object literal with user properties which will be written into newly created user object
const user = repository.create() // same as const user = new User();
const user = repository.create({
    id: 1,
    firstName: "Timber",
    lastName: "Saw",
}) // same as const user = new User(); user.firstName = "Timber"; user.lastName = "Saw";

save

  • Entity 또는 Entity 배열을 저장
  • 이미 Entity가 존재한다면 업데이트 되고 업다면 삽입한다.
  • 정의되지 않는 속성의 경우는 건너뛰기 떄문에 부분업데이트도 가능하다
  • 저장된 Entity를 반환한다.
await repository.save(user)
await repository.save([category1, category2, category3])

find

  • Finds entities that match given FindOptions.
const timbers = await repository.find({
    where: {
        firstName: "Timber",
    },
})

findOne

  • Finds the first entity that matches given FindOptions.
  • 단 Where절의 프로퍼티로 undefined가 넘어갈 경우 첫번쨰 객체를 반환한다..! 관련 이슈
const timber = await repository.findOne({
    where: {
        firstName: "Timber",
    },
})

findOneBy

  • Finds the first entity that matches given FindOptionsWhere.
const timber = await repository.findOneBy({ firstName: "Timber" })

update

  • Partially updates entity by a given update options or entity id.
await repository.update({ age: 18 }, { category: "ADULT" })
// executes UPDATE user SET category = ADULT WHERE age = 18

await repository.update(1, { firstName: "Rizzrak" })
// executes UPDATE user SET firstName = Rizzrak WHERE id = 1

delete

  • Deletes entities by entity id, ids or given conditions:
await repository.delete(1)
await repository.delete([1, 2, 3])
await repository.delete({ firstName: "Timber" })

softDelete and restore

  • Soft deleting and restoring a row by id
const repository = dataSource.getRepository(Entity)
// Delete a entity
await repository.softDelete(1)
// And You can restore it using restore;
await repository.restore(1)

📘QueryBuilder Pattern

SQL 쿼리문들을 이용하여 조건들이 반영된 Entitiy를 얻을수 있도록한다.

예를 들어 이 구문의 결과는

const firstUser = await dataSource
    .getRepository(User)
    .createQueryBuilder("user")
    .where("user.id = :id", { id: 1 })
    .getOne()

다음과 같다.

User {
    id: 1,
    firstName: "Timber",
    lastName: "Saw"
}

사용 예시는 좋은 글이 있어 첨부로 대신합니다.
[NestJS/TypeORM] QueryBuilder for NestJS (TypeORM Refactoring)

@rimo030 rimo030 self-assigned this Nov 14, 2023
@rimo030 rimo030 added the NestJS NestJS and its associated libraries label Nov 14, 2023
@kakasoo
Copy link
Collaborator

kakasoo commented Dec 17, 2023

TypeORM에서 SQL을 표현하는 방법

SELECT * FROM PRODUCT AS P
  INNER JOIN PRODUCT_REQUIRED_OPTION AS PRO ON P.id = PRO.product_id
this.dataSource
  .createQueryBuilder()
  .from(ProductEntity, 'p')
  .select('*')
  .innerJoin(`p.productRequriedOptions`, 'pro', 'pro.isSale = true');

this.productRepository
  .createQueryBuilder('p')
  .select('*')
  .innerJoin('p.productRequriedOptions', 'pro', 'pro.isSale = true');

this.productRepository
  .createQueryBuilder('p')
  .select('*')
  .leftJoin('p.productRequriedOptions', 'pro')
  .where('pro.isSale = true');

this.productRepository.find({
  relations: {
    productRequriedOptions: true,
  },
  where: {
    productRequriedOptions : {
      isSale: true
    }
  }
});

이것들은 모두 같은 의미입니다.

@kakasoo
Copy link
Collaborator

kakasoo commented Dec 17, 2023

SQL injection

  • A = TRUE : ORM에서 문자열로 확정된 값을 그대로 넣는 것은 안전한 편
  • A = ${isTrue} : ORM에서 확정되지 않은 값을 그대로 넣는 것은 위험한 편
  • A = :isTrue, { isTrue: true } : ORM이 쿼리를 날리기 전에 전처리하기 때문에 안전한 편

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
NestJS NestJS and its associated libraries
Projects
None yet
Development

No branches or pull requests

2 participants