Node 수업내용 21.06.16 Sequelize
시퀄라이즈는 ORM(Object Relational Mapping)으로 분류된다.
어제했던 CRUD를 시퀄라이즈의 API를 통해 간편하게 실행할 수 있다는 장점이 있다.
npm init -y
npm i express
npm i nodemon
npm i mysql2
npm i sequelize
npm i sequelize-cli -g(글로벌)
npm i sequelize-auto
sequelize init
까지 하면 필요한 모듈들과 config파일 등이 설치된다.
CLI는 config파일을 만들어주는 역할을 한다(JS로 코드작성을하면 DB테이블을 만들어주는 역할.)
Sequelize-auto는 시퀄라이즈 모듈을 조금 더 편리하게 만들어둔 모듈이다.
우선 auto를 사용하지 않고 접속테스트를 해보자.
async(비동기)메서드는 정상작동전에 에러가 날 가능성이 있기때문에 try-catch로 에러를 잡아주어야 한다.
해당 js파일을 실행하면 localhost:3000번에서 정상작동하는 모습을 볼 수 있다.
const express = require("express");
const app = express();
const { Sequelize } = require("sequelize");
const sequelize = new Sequelize("mysql", "root", "d394", {
host: "localhost",
dialect: "mysql",
});
const port = 3000;
app.get("/", (req, res) => {
res.send("Hello Express!");
});
app.listen(port, () => {
console.log(`${port}번 서버 대기중`);
});
app.get("/connectdb", (req, res) => {
connect();
res.end("DB Connection test");
});
async function connect() {
try {
await sequelize.authenticate(); //접속대기
console.log("connected");
} catch (err) {
console.log(err);
}
}
Sequelize-auto
const SequelizeAuto = require("sequelize-auto");
const auto = new SequelizeAuto("nodejs", "root", "d394", {
host: "localhost",
port: "3306",
dialect: "mysql",
});
auto.run((err) => {
if (err) throw err;
console.log("complete!");
});
run메소드의 설명이 any라고 떠도 괜찮다. 레퍼런스가 되지 않아서 일어나는 일이지만 작동은 정상적으로 된다.
해당 auto를 node로 실행한다면 지정한 db에 있는 테이블들을 불러온다.
Find
const initModels = require("./models/init-models");
const Sequelize = require("sequelize");
const sequelize = new Sequelize("nodejs", "root", "d394", {
host: "localhost",
dialect: "mysql",
});
const models = initModels(sequelize);
// models.users.findAll().then((results) => {
// console.log(results);
// });
async function findAllFromUsers() {
const results = await models.users.findAll();
console.log(results);
}
findAllFromUsers();
주석처리된 부분과 비동기 메서드 둘 다 같은 결과를 출력해낸다.
JS의 장점은 많이쓰는 스크립트를 좌측 사진과 같이 모듈화시킬 수 있다는 것이다. 해당 모듈을 만들어 오른쪽처럼 사용했다. 그리고 Sequelize의 부호(>, <, = 등)들은 코드로 지정되어 있기때문에 Op객체를 불러와서 사용해야 한다.
Sequelize 공식 Document - (2) Querying
해석과 설명을 곁들인 Sequelize 도큐먼트 정복, 그 2편
velog.io
해당 부호들에 대한 코드는 위의 링크로 들어가면 나온다.
이후 연습으로 조건을 두가지로 걸어 검색해보았다.
const { Op, models } = require("./mysequelize");
// models.users.findAll().then((results) => {
// console.log(results);
// });
//SELECT * FROM products WHERE price > 10000;
// async function findAllFromProducts() {
// const product = await models.products.findAll({
// where: {
// price: {
// [Op.gt]: 10000,
// },
// },
// });
// const json = JSON.stringify(product);
// console.log(json);
// }
async function findAllFromUsers() {
const users = await models.users.findAll({
where: {
age: {
[Op.gte]: 40,
},
married: {
[Op.gt]: 0,
},
},
});
const json = JSON.stringify(users);
console.log(users);
}
//findAllFromProducts();
findAllFromUsers();
주석처리된 부분은 앞서 연습했던 부분들이다.
attributes로 얻고싶은 column을 정해준 뒤에 where로 원하는 row의 조건을 설정한다. 그리고 받아온 정보를 역직렬화 시켜서 출력하면 위와 같이 원하는 정보가 출력된다.
const express = require("express");
const initModels = require("./models/init-models");
const app = express();
const { Op, Sequelize } = require("Sequelize");
const sequelize = new Sequelize("nodejs", "root", "d394", {
host: "localhost",
dialect: "mysql",
});
const models = initModels(sequelize);
const port = 3000;
app.get("/", (req, res) => {
res.send("Hello Express!");
});
app.listen(port, () => {
console.log(`${port}번 서버 대기중`);
});
app.get("/api", async (req, res) => {
let json = await connect();
res.send(json);
});
async function connect() {
try {
const users = await models.users.findAll({
attributes: ["name", "age"],
where: {
age: {
[Op.gte]: 30,
},
},
});
const json = JSON.stringify(users);
console.log("here");
console.log(json);
return json;
//접속대기
console.log("connected");
} catch (err) {
console.log(err);
}
}
a문제는 connect 메서드 비동기 실행시 DB를 불러올 수는 있었지만 그것을 라우터에 전달할 수 가 없었다. 하지만 알아보니 (req,res)를 비동기로 실행할 수 있었다.
위 사진처럼 비동기로 요청과 반응을 실행하고 불러온 DB의 내용을 마찬가지로 비동기로 받은 뒤 해당 내용을 res.send로 출력해주었다.
완성