mysql
서버측에서 데이터베이스 중 하나인 mysql을 이용할 수 있게 하는 3 party pakage이다.
사용법은 아래 코드 참조.
아래서 볼 수 있듯이 연결된 DB 객체를 바탕으로 query라는 method를 이용해서 쿼리문을 그대로 적어주는 것이 문법이다.
다만 require("mysql2")로 import를 하면 콜백함수만 쓸 수 있고, promise는 사용할 수 없다.
콜백함수를 사용하는 이유 - (데이터베이스에 연결하는 것은 시간이 걸리는 작업이기 때문이다.(비동기),
밑에 있는 코드가 만일 데이터베이스의 결과를 이용하는 구문이라면, 즉 쿼리문이 실행되고 나서 실행되어야 하는 동작이라면, 해당 구문이 완료되기를 기다려야 하기 때문에 콜백함수를 이용한다.)
const mysql = require("mysql2");
// DB연결
const conn = mysql.createConnection({
host: "localhost",
user: "user",
password: "1234",
database: "kdt",
});
// select
function getVisitors(cb) {
conn.query(`SELECT * FROM visitor`, function (err, rows) {
if (err) {
throw err;
}
console.log("Visitor.js>", rows);
/*
Cvisitor.js> [
{ id: 1, name: '홍길동', comment: '내가 왔다' },
{ id: 2, name: '이찬혁', comment: '으라차차' }
]
*/
cb(rows);
});
}
// insert
function postVisitor(data, cb) {
console.log(data);
const sql = 'INSERT INTO visitor (name, comment) VALUES (?, ?)';
const values = [data.name, data.comment];
conn.query(sql, values, (err, rows) => {
if(err) throw err;
console.log('Visitor.js>', rows)
cb(rows.insertId); // rows.insertId의 정보를 controller에 넘겨줌.
})
}
// update
function patchVisitor(data, cb) {
const sql = 'UPDATE visitor SET name = ?, comment = ? where id= ?';
conn.query(sql, [data.name, data.comment, data.id], function (err, rows) {
if (err) {
throw err
}
console.log('patchVisitor getVisitor.js >', rows);
cb(rows);
});
}
// delete
function deleteVisitor(id, cb) {
const sql = 'DELETE FROM visitor where id = ?'
conn.query(sql, [id], function(err, rows) {
if (err) {
throw err
}
console.log('deleteVisitor visitor.js>', rows);
cb(rows);
});
}
mysql/promise
mysql에서 promise를 이용하고 싶다면 import와 createconnection이라는 method를 createpool로 바꿔주면 된다.
주의할 점은 받아온 promise 객체는 바로 사용할 수 없다는 점이다.
구조분해 할당을 한번 해 주어야 배열로 이용할 수 있다.
// 다른점 1
const mysql = require("mysql2/promise");
// DB연결
const conn = mysql.createPool({
host: "localhost",
user: "user",
password: "1234",
database: "kdt",
});
async function insertUser(data) {
const sql = 'INSERT INTO USER (userid, name, pw) VALUES (?, ?, ?)'
const userInfo = [
data.id,
data.name,
data.pw,
]
// 다른점 2
const [result] = await conn.query(sql, userInfo)
return result;
}
async function postLogin(data, res) {
const sql = 'SELECT * FROM USER where userid = ?'
try {
const [result] = await conn.query(sql, [data.id]);
if(result[0].pw == data.pw) {
res.render('update', {userInfo: result[0]});
return;
} else {
return ['아이디 혹은 비밀번호가 달라요.'];
}
}catch {
return ['아이디가 없습니다.'];
}
}
sequelize
sql의 원래 뜻인 sequel에서 차용해서 sequelize라고 한 3 party pakage인 듯하다.
mysql을 더 쉽게 이용할 수 있다. (promise 등 이용 가능)
이용하려면 import 이후 테이블 구조를 정의하고 전체 스키마와 전체 모델 구조를 정의해야한다.
// json파일. 파일명은 config.json
{
// 개발용 환경설정
"development": {
"username": "user",
"password": "1234",
"database": "kdt",
"host": "127.0.0.1",
"dialect": "mysql"
},
// 다른 환경설정이 필요할 시 적음
"production": {},
"test": {}
}
개별 테이블, 모델 구조 정의
// Visitor.js 파일
// TODO: visitor 모델 정의
// 테이블 구조를 정의한다 라고 생각
// 시퀄라이즈 모델이랑 mysql 테이블 연결
const Visitor = function(Sequelize, DataTypes) {
// Sequelize는 models/index.js에서의 sequelize (인스턴스(객체))
// DataTypes는 models/index.js에서의 Sequelize (클래스 (객체청사진))
const model = Sequelize.define(
'visitor', // param1: 모델 이름 설정,, (1) -> !시퀄라이즈 에서의 모델명을 뜻함...! DB의 모델명은 (2)번 table name
{ // id int AI PK
id: {
type: DataTypes.INTEGER,
allowNull: false,
primaryKey: true,
autoIncrement: true
},
name: {
// name: VARCHAR(10) NOT NULL
type: DataTypes.STRING(10),
allowNull: false
},
comment: {
type: DataTypes.TEXT('medium')
}
}, // param2: 컬럼 정의
{
tableName: 'visitor', // 실제 DB에 있는 테이블 이름 명시 (2) 얘만 있어도 됨.
freezeTableName: true, // 첫 번째 인자로 넘겨준 모델 이름을 그대로 테이블 이름으로 고정 (3): 2가 없을 시 1과 3만으로 테이블 생성 가능, 직접적으로 DB이름을 정하는 것은 2
// 시퀄라이즈는 기본적으로 테이블 이름을 모델 + s로 가져감
// charset, collate 값이 있는데 db 정의할 때 한글 인코딩 가능하도록 만들어 뒀기 때문에 따로 설정 불요
timestamps: false
// - timestamps: 데이터가 추가되고 수정된 시간을 자동으로 컬럼으로 만들어서 기록하는 옵션
// true로 설정시 컬럼에 시간이 추가된다.
} // param3: 모델 옵션 정의
)
return model;
}
module.exports = Visitor;
전체 모델 구조 정의
// index.js
// 전체 모델에 대한 정의
const Sequelize = require('sequelize');
// json에 있는 환경설정 가져오기. ['development']는 .표기법이 아닌 []표기법 이용
const config = require(__dirname + '/../config/config.json')['development'];
console.log('config > ', config);
/*
config > {
username: 'user',
password: '1234',
database: 'kdt',
host: '127.0.0.1',
dialect: 'mysql'
}
*/
const db = {};
// 시퀄라이즈 객체 선언 시에 매개변수로 다음 정보들을 받음.
const sequelize = new Sequelize(
config.database,
config.username,
config.password,
config
)
db.sequelize = sequelize;
db.Sequelize = Sequelize;
db.Visitor = require('./Visitor')(sequelize, Sequelize); // 첫번째 인자: 인스턴스, 두번째 인자: 객체 청사진(class)
// models/Visitor.js에서 정의한 모델이 db.Visitor 에 들어감
// db = { sequelize: sequelize, Sequelize: Sequelize, Visitor: ~~~}
module.exports = db;
// db라는 변수는 내보냄
// 시퀄라이즈 객체를 만들고 모듈로서 내보내서 "다른 파일에서 모두 같은 객체를 사용할 수 있게 하는 것"
app.js
const express = require('express');
const app = express();
const db = require('./models/index');
const router = require('./routes/index');
app.set('view engine', 'ejs');
// app.set('views', './views');
app.set('views', (__dirname + '/views'));
app.use( express.static('static'));
app.use(express.urlencoded( { extended: true}));
app.use(express.json());
app.use(router);
app.get('*', function(req, res) {
res.status(404).render('404');
})
db.sequelize.sync({force: false}).then(function() {
// force: false => 테이블이 없으면 생성.
// force: true => 테이블 무조건 생성 (만약 DB가 있다면 다 삭제하고 다시 생성 -> prod에서 사용)
app.listen(8000);
})
1:1, 1:다 등 테이블 간의 관계 설정하기.
// 1) Player : Profile = 1: 1
// 한 선수당 하나의 프로필을 가지도록 함
Player.hasOne( Profile, { foreignKey: 'player_id',
sourceKey: 'player_id',
onDelete: 'CASCADE',
onUpdate: 'CASCADE'});
Profile.belongsTo( Player, {
foreignKey: 'player_id',
targetKey: 'player_id'
})
// 2) Team : Player = 1: N
// 한 팀에는 여러 선수가 존재
Team.hasMany(Player, {foreignKey: 'team_id',
sourceKey: 'team_id'});
Player.belongsTo( Team, {
foreignKey: 'team_id',
targetKey: 'team_id'
})
// TODO: 관계를 정의한 모델들을 db 객체에 저장
db.sequelize = sequelize;
db.Sequelize = Sequelize;
db.Player = Player;
db.Profile = Profile;
db.Team = Team;
module.exports = db;
'포스코x코딩온' 카테고리의 다른 글
[포스코x코딩온] 풀스택 부트캠프 8주차 정리 -1 (비밀번호 암호화, socket) (0) | 2023.12.13 |
---|---|
[포스코x코딩온] 풀스택 부트캠프 7주차 정리 2 - Cookie, Session, dotenv, aws, 서버구축, jwt (1) | 2023.12.09 |
[포스코x코딩온] 풀스택 부트캠프 6주차 정리 2 - 파일업로드, MVC (0) | 2023.11.30 |
[포스코x코딩온] 풀스택 부트캠프 6주차 정리 1 - form전송, 동적 form 전송 (0) | 2023.11.28 |
[포스코x코딩온] 풀스택 부트캠프 5주차 정리 2 - 구조분해 할당, 스프레드 연산자, promise (0) | 2023.11.23 |