될때까지

((AFTER 과제1)) 프리온보딩 첫번째 과제 스터디1 본문

프로젝트/프리온보딩

((AFTER 과제1)) 프리온보딩 첫번째 과제 스터디1

랖니 2022. 10. 24. 23:15
728x90

1. ORM 연결 mysql2로 변경하기

ORM을 사용하지 말고 raw query로 작성해야했는데 DB와 연결할때는 typeorm을 사용했다.
ORM 자체를 사용하지 않고 DB와 연결할 수 있는 방법이 있는데 그땐 왜그랬을까..!!! 코드를 수정해보자.
먼저 설치된 typeorm을 삭제한다.

npm uninstall typeorm

그리고 mysql2를 설치한다.

npm install mysql2

DB연결 정보들은 .env파일에 저장하여 외부로 노출되지 않도록 숨겨줬다.

// .env

DATABASE_URL = mysql://유저이름:비밀번호@호스트주소:포트번호/데이터베이스이름
MYSQL_CONNECTION = mysql
MYSQL_HOST = 127.0.0.1
MYSQL_PORT = 3306
MYSQL_USERNAME = name
MYSQL_PASSWORD = password
MYSQL_DATABASE = database name

models 폴더에서 DB에 접근하는 코드들을 작성할 예정이다.
mysql 연결 코드들도 models안에 mysql.js파일을 만들어서 작성해준다.

// models > mysql.js
const mysql = require("mysql2/promise");

const pool = mysql.createPool({
    host: process.env.MYSQL_HOST,
    port: process.env.MYSQL_PORT,
    user: process.env.MYSQL_USERNAME,
    password: process.env.MYSQL_PASSWORD,
    database: process.env.MYSQL_DATABASE,
});

module.exports = pool;

DB에 다녀오는 작업들은 비교적 시간이 소요된다.
따라서 비동기적으로 처리해야된다 판단을 했고 프로미스를 지원하는 mysql2를 사용했다.
mysql2는 또 async, await과 호환이 잘된다고 한다.
DB 연결 방법으로는 createPool을 사용했다.
공식문서에 따르면 pool은 이전 연결을 재사용하여 mysql 서버에 접속하는 데 걸리는 시간을 줄여주기 때문에 효율적이라고 한다.

그럼 DB연결은 끝!

 

2. pool.query의 반환값 !== typeorm.query의 반환값

typeorm을 사용해 DB와 연결했을 때는, query의 결과값이 [{id:11}] 이렇게 반환됐다.

그래서 모델단에서 user를 [] 한번 덧대서 벗겨줬고,

// models > user.js

const getUserByPhone =  async (phone) => {
  const [user] = await myDataSource.query(`
    SELECT * FROM users 
    WHERE phone = ? AND deleted=?
  `, [phone, false])
  return user;
};

서비스단에서 핸드폰번호 중복의 유저를 처리할 때 if (user)로 간단하게 중복 처리를 할 수 있었다.

모델단에서 실행된 결과 user에는 같은 연락처의 유저가 있다면 {id:3, name:'아무개'..}처럼 객체가 담기게 되고, 유저가 없다면 undefined가 반환되기 때문이다.  undefined는 falsy이기 때문에 if문을 통과하여 user를 성공적으로 생성할 수 있었다.

// services > user.js

const createUser = async (name, birth, height, phone) => {
  const user = await userDao.getUserByPhone(phone)
  if (user) {
    const error = new Error('이미 등록된 phone입니다.')
    error.statusCode = 400
    throw error
  }
  await userDao.createUser(name, birth, height, phone)

  return;
};

이번에는 mysql2를 사용해 DB와 연결했는데, query의 결과값이 typeorm과 다르게 나왔다. [[{id:20}], [{필요없는 정보}]] 이렇게 반환됐다. 

[]를 한번 씌워서 값을 벗기고 콘솔에 찍어봤는데 아직도 배열안에 담겨있잖아?

const getUserByPhone = async (phone) => {
  const [user] = await pool.query(
    `
      SELECT 
          id
      FROM 
          users
      WHERE 
          phone = ?
    `,
    [phone],
  );
    console.log('ddd', user)   // ddd [ { id: 20 } ]
  return user;
};

한번 더 벗기면 된다는 동기분의 말을 듣고 해봤더니 해결...♥️♥️

const getUserByPhone = async (phone) => {
  const [user] = await pool.query(
    `
      SELECT 
          id
      FROM 
          users
      WHERE 
          phone = ?
    `,
    [phone],
  );
    console.log('ddd', user)   // ddd { id: 20 }
  return user;
};

그럼 이제 위에서 작성했던 연락처 중복 로직을 단순하게 if (user)로 사용할 수 있다.
그전에는 if ( user.length > 0 )으로 작성해서 마음에 안들었는데, 깔끔해졌다.!!
같은 문제를 겪었었다니 ㅋㅋㅋ 그리고 한번 더 벗길수 있다니!! 재밌었던 문제였다.

728x90