티스토리 뷰

반응형

안녕하십니까 저번에 node js 기반에서 DB를 사용하기 위한 ORM인 sequelize에 대해 소개한 글을 작성했습니다!

그리고 이번에는 제가 프로젝트를 진행하면서 sequelize를 어떻게 사용했는지 간단한 기능들을 소개하려고 합니다.

 

물론 공식 홈페이지에 작성되어 있는 Manual보다는 아니며, 이 친구는 그냥 이런식으로 사용했구나! 라고 가볍게 봐주세요.

 

create, select 같은 단순 CRUD는 넘어가고 제가 소개할 기능은 다음과 같습니다.

 

1. upsert

2. transaction

3. raw query

4. Hooks ( trigger )

 

1. upsert

upsert라고 들어보셨나요??? 뭔가 합친말 같지 않나요? insert + update를 합친거에요.

upsert는 insert하려는 data가 db에 없으면 insert, 있으면 update를 할 수 있도록 해주는 메서드 입니다.

사용방법은 create, findOne 처럼 간단합니다.

	// 메서드 안에는 JSON Oject가 들어가야 합니다. 밑은 제가 그냥 만든 기능이에요.
          UserVO.upsert(Utiles.sequelizeToObject(joinUser))
            .then(user => {
              resolve(Utiles.responseToJson(200, token));
            })
            .catch(err => {
              reject(Utiles.responseToJson(500.1, "Data Error"));
            });

어때요 참 쉽죠??? 결과 화면은 제가 찍질 못했네요 ㅠㅠ

실행을 해보면 select 이후 update나 insert를 하는 것을 보실 수 있을거에요.

 

2020-1-15 추가

참고로 upsert는 내부적으로 primary key나 unique key를 찾아서 있으면 update, 없으면 insert를 합니다.

 

// Sequelize model.d.ts upsert주석

Insert or update a single row. An update will be executed if a row which matches the supplied values on

either the primary key or a unique key is found.

 

2. transaction

db에서 말하는 transacton이란 작업의 시작부터 해서 commit이나 rollback 까지 이르는 작업의 단위를 transaction이라고 합니다.

 

그 전에 transaction은 원자성(Atomicity), 일관성(Consistency), 독립성(Isolation), 영구성(Durability)을 보장합니다.

이것을 ACID라고 합니다. 각가의 특징은 google에 검색해보세요.

 

sequelize를 이용하여 transaction또한 관리할 수 있습니다. 

sequelize를 이용하면 auto commit을 이용할 수도 있고, 개발자가 직접 commit 및 rollback의 작업을 할 수도 있습니다.

auto commit은 manual에 기재되어 있으니 여러개의 쿼리를 실행 하는 동시 트랜젝션을 사용해보겠습니다.

	sequelize
        .transaction(
          {
            isolationLevel: // Mysql transaction 장애 예방 
              Sequelize.Transaction.ISOLATION_LEVELS.READ_COMMITTED
          },
          t1 => { // promise를 이용하거나 cls라는 모듈을 사용할 수 있습니다!
            return Promise.all([
              PointTransferVO.create(
                Utiles.sequelizeToObject(pointTransferVO),
                {
                  transaction: t1
                }
              ),
              PointHistoryVO.create(
                Utiles.sequelizeToObject(pointHistorySender),
                {
                  transaction: t1
                }
              ),
              PointHistoryVO.create(
                Utiles.sequelizeToObject(pointHistoryReceiver),
                { transaction: t1 }
              )
            ]);
          }
        )
        .then(r => {
          resolve(Utiles.responseToJson(200, "success transfer"));
        })
        .catch(err => {
          reject(Utiles.responseToJson(500.1, "failed transfer"));
        });

transaction: t1을 설정 함으로써 하나의 트랜젝션으로 관리를 하겠다는 의미 입니다!

하지만 꼭 하나의 transaction뿐 아니라 여러 transaction을 이용할 수도 있으니 manual을 참고 해주세요.

 

역시 결과 화면은 찍지 못했지만

query들이 실행 후 commit까지 하는 결과를 볼 수 있습니다.

 

3. raw query

ORM을 사용하면 결국 한계가 느껴지는 부분이 있습니다. 저는 join이나 sub query를 작성하면서 느꼈는데요,

sequelize는 orm 뿐 아니라 직접 query를 작성하여 실행할 수도 있습니다. 

     sequelize
        .query(
          `SELECT SUM(money) as money, name
      FROM (
      SELECT c.TYPE, IF(c.TYPE = "GET", SUM(money), SUM(money) * -1) AS money, u.name
      FROM c_point_history AS c RIGHT OUTER JOIN c_users AS u
      ON c.user_idx = u.user_idx
      WHERE c.user_idx = '${user.user_idx}' GROUP BY c.TYPE) AS b `,
          { type: Sequelize.QueryTypes.SELECT, raw: true }
        )
        .then(point => {
          resolve(Utiles.responseToJson(200, point));
        });

JOIN을 이용하기 위해서 다음과 같은 쿼리를 작성했으며, 밑에 type 지정 및 raw: true를 해줬습니다.

 

4. Hooks (TRIGGER)

sql에서 trigger라고 이벤트가 발생되었을 때 해당 sql을 실행시키는 프로시저라고 할 수 있으며

sequelize에서는 hooks이라고 표현한다고 하는데 아직은 사용해보지 않았으며, 이러한 기능이 있다고 합니다.

 

이 외에도 다양한 기능들이 무수히 많습니다.

 

좀 더 사용해보고 괜찮은 기능이 있으면 소개해드릴게요!

 

참고

transaction

https://k39335.tistory.com/28


mysql isolation level

http://gywn.net/2012/05/mysql-transaction-isolation-level/

반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함