데브코스 웹풀스택 과정/TIL
0930 타임 존(timezone) 설정, 디비 연동 및 쿼리 가져오기
thinktank911
2025. 9. 30. 16:04
ZEROFILL 옵션
- 데이터를 저장하거나 표시할 때 지정된 길이에 맞춰 숫자 앞을 0으로 채우는 기능
- MySQL 의 int, tinyint 등 정수형 타입과 함께 사용
- ex> INT(5) ZEROFILL로 선언된 컬럼에 숫자 '1'이 저장되면, 결과는 '00001'로 표시
DB 연동
// A simple SELECT query
connection.query(
'SELECT * FROM users',
function (err, results, fields) {
console.log(err);
console.log(results); // results contains rows returned by server
console.log(fields); // fields contains extra meta data about results, if available
}
);
- results : 쿼리 결과
- fields : 테이블정의. 메타 데이터
timezone 추가
- DB의 created_at 시간 값을 노드 서버에 가져올 때 DB 시간대와 다르다
conn.query(
'SELECT * FROM `users`',
function (err, results, fields) {
var {id, email, name, created_at} = results[0];
console.log(id);
console.log(email);
console.log(name);
console.log(created_at);
}
);
1) node에서 timezone 설정

- 무시됨
2) db에서 timezone 설정
- 전체 데이터베이스의 timezone을 'Asia/Seoul'로 변경 => 바뀌지 않음
- 현재 session의 timezone을 바꿈 => 한국 시간으로 잘 나옴
- 타임존이 제대로 설정되었는지 조회
-- 전체 데이터베이스 timezone 설정
SET GLOBAL time_zone = 'Asia/Seoul';
-- 현재 session timezone 설정
SET time_zone = 'Asia/Seoul';
-- 타임존 설정값 조회
SELECT @@global.time_zone, @@session.time_zone;
3) node에서 dateStrings값 true로 변경

- connection 프로퍼티의 dateStrings을 true로 추가
- 날짜를 출력할 때 뒤에 Z가 붙는데 해당시간이 UTC (세계 협정시) 기준임을 나타내는 표시
=> Z를 빼고 YYYY-MM-DD HH:MM:SS 날짜 형식대로 표기되도록 하는 역할
- 날짜를 출력할 때 뒤에 Z가 붙는데 해당시간이 UTC (세계 협정시) 기준임을 나타내는 표시
db 모듈화
- mariadb.js에서 connection 모듈을 export 해준다.
// db 모듈화
module.exports = connection
- mariadb.js에 있던 connection.query를 users.js로 옮겨서 구현해보기

SELECT SQL 쿼리 형식 - 로그인
conn.query(sql문,변수,콜백함수(err, results, fields))
- sql문 안에 변수는 ?로 표시한다.
- conn.query의 두번째 매개변수에 ?에 들어갈 변수를 작성
- 콜백함수의 인자는 순서대로 err, results, fields로 생략 가능하나 순서를 잘 지켜서 작성해줘야 한다.
// 로그인
router.post('/login',(req,res)=>{
const {email, pwd} = req.body
// SELECT 쿼리문
conn.query(`SELECT * FROM users WHERE email= ?`, email,
function (err, results) {
var loginUser = results[0]
if(loginUser && loginUser.pwd === pwd){
res.status(200).json({
message : `${loginUser.name}님 환영합니다.`
})
}
INSERT SQL 쿼리 형식 - 회원가입
conn.query('insert sql문',변수배열,콜백함수)
- INSERT문 안에 변수는 똑같이 ?로 표시해준다.
- 변수가 여러 개인 경우 배열로 받을 수 있다.
// 회원가입
router.post('/join',(req,res)=>{
const userInfo = req.body
if(Object.keys(userInfo).length > 0){
const {email, name, pwd, contact} = userInfo
// INSERT 쿼리문
conn.query(`INSERT INTO users (email, name, pwd, contact)
VALUES (?, ?, ?, ?)`, [email, name, pwd, contact],
function (err, results) {
if(results.length){
res.status(201).json(results)
DELETE SQL 쿼리 형식 - 회원삭제
- SELECT문과 동일하게 SQL문 변수에 ? 작성하고, 두번째 인자에 변수 담는다.
.delete((req,res)=>{
let {email} = req.body
// DELETE 쿼리문
conn.query(`DELETE FROM users WHERE email= ?`, email,
function (err, results) {
if(results.length){
res.status(200).json(results)
}
else{
res.status(404).json({
message : "존재하지 않는 회원입니다."
})
}
}
);
users.js 코드정리 - 리팩토링
- 필요없는 코드 없애기
- 변경 전 : if문이 중첩되어 복잡하다.
- 1차 변경 : login정보유무와 비밀번호 일치 여부 조건을 합친다.
- 변경 후 : else 예외처리 메세지를 요즘 트렌드인 '아이디 또는 비밀번호가 일치하지 않습니다'로 바꿔 else if문을 날린다.
// 변경 전
var loginUser = results[0]
if(loginUser){
if(loginUser.pwd === pwd){
res.status(200).json({
message : `${loginUser.name}님 환영합니다.`
})
}
else{
res.status(400).json({
message : "비밀번호가 일치하지 않습니다."
})
}
}
else{
res.status(404).json({
message : "회원 정보가 없습니다."
})
}
// 1차 변경
var loginUser = results[0]
if(loginUser && loginUser.pwd === pwd){
res.status(200).json({
message : `${loginUser.name}님 환영합니다.`
})
}
else if(loginUser && loginUser.pwd !== pwd){
res.status(400).json({
message : "비밀번호가 일치하지 않습니다."
})
}
else{
res.status(404).json({
message : "회원 정보가 없습니다."
})
}
// 변경 후
if(loginUser && loginUser.pwd === pwd){
res.status(200).json({
message : `${loginUser.name}님 환영합니다.`
})
}
else{
res.status(404).json({
message : "아이디 또는 비밀번호가 일치하지 않습니다."
})
}
- 주석 수정 : 코드를 보고 알 수 있으면 지우기
- 문자열 오타 수정 및 변수로 sql문과 values 빼기

단축 평가
- 단축 평가는 && (논리곱) 또는 || (논리합) 같은 논리 연산자를 사용할 때, 표현식의 결과가 이미 확정되었다면 나머지 피연산자 평가를 생략하는 기능이다. 이를 통해 불필요한 연산을 줄여 성능을 향상시키고, if 문 없이 조건부 로직을 간결하게 작성할 수 있
let sql = `SELECT * FROM channels WHERE user_id = ?`
// 단축평가 : 앞에 먼저 true/false 체크하고 true면 다음 조건 체크
userId && conn.query(sql, userId,
function (err, results) {
if(results.length){
res.status(200).json(results)
return
}else{
notFoundChannel(res)
return
}
}
)
res.status(400).end()
- 단축 평가를 통해 적절한 값을 얻을 수 있을 때 사용한다. channel.js의 채널 전체 조회 api 예외 처리는 if문을 사용하겠다.
if(userId){
conn.query(sql, userId,
function (err, results) {
if(results.length){
res.status(200).json(results)
return
}else{
notFoundChannel(res)
return
}
}
)
}
else{
res.status(400).end()
}
DB의 시간대가 이상하게 저장될 때, 서버에서 이상하게 출력될 때 TIMEZONE이 어떻게 셋팅되어 있는지 확인하고 셋팅할 수 있는 방법에 대해 배웠다. MYSQL에 ZEROFILL이 있어서 신기했다. 오라클을 사용할 땐 직접 LPAD()나 RPAD() 메소드 써서 채워줬다. conn.query 메소드를 이용해 sql문을 직접 가져와서 db 결과를 가져왔는데, 이를 공통함수로 빼서 구현할 수 있는지 여부와 프로시저를 사용했을 때 서버 호출법에 대해 더 알아봐야겠다.