본문 바로가기

블록체인 기반 핀테크 및 응용 SW개발자 양성과정 일기

[37일차 복습 및 정리] MySQL sequelize 시퀄라이즈 세팅, Node.js express CRUD 시퀄라이즈 사용법

반응형

Sequelize 세팅

 

 

 

0 . npm init   명령 first 

1. npm install express nunjucks sequelize sequelize-cli mysql2 설치하기 

책에는 install morgan / npm i -D nodemon 도 적혀있다. 

npm install nodemon -> 은 나중에! server 켰다 껐다 연습해야해서 

 

-nunjucks : html render를 위한 패키지 

-Sequelize-cli : sequelize 명령어를 실행하기 위한 패키지 

-mysql2 : MySQL과 Sequelize를 이어주는 드라이버 역할 (DB프로그램x) 

 

 

 

2. npx sequelize init 

npm - 우리가 다운받지 않은 상태에서 폴더 다운 받는 개념 (기본적인 틀 제공) 

npx - 다운받은 폴더를 실행시켜서 세팅해주기 

* 전역없이 명령어로 사용하려면 앞에 npx 붙이기

 

* config.json 분석

 

config, migrations, models, node_modules, seeders, package-lock.json 폴더가 생겼다. 

 

config폴더 안 config.json 에는 

"development" - 실제 서버 연결시 

"test" - 테스트용 

"production" - 상품 정보 담는 3가지 객체가 생성되어 있다. 

 

config - 접속 정보를 저장해주는 객체 

 

 

 

 

 

 

 

* models- index.js 분석

'use strict';  //없어도 상관 없다.

const fs = require('fs');
const path = require('path');
const Sequelize = require('sequelize');  //Sequelize
const basename = path.basename(__filename);
const env = process.env.NODE_ENV || 'development'; //test할 때 development를 test로 바꿔 
const config = require(__dirname + '/../config/config.json')[env]; 
// env 위에 정의되어 있음. 우리는env 설정안했음. 지금 env = development 값 
// config는 요걸 가져옴 
// config = config파일 안 development 의 객체 값이 된다. 
const db = {};  //빈 객체로 선언 

let sequelize;  //sequelize
if (config.use_env_variable) { // config에 use_env_variable이라는 정보가 있으면 ~
  sequelize = new Sequelize(process.env[config.use_env_variable], config);
} else { //요게 우리가 실행될 것 
  sequelize = new Sequelize(config.database, config.username, config.password, config);
} // new = 함수가 객체로 변한다 / 결과적으로 요 값이 객체로 변하겠구나~ 알 수 있음.  
//config 어디서 가져왓냐면 위에 8번줄
// development 객체 안의 내용을 내 db 내용과 같도록 정보 바꾸기 

fs
  .readdirSync(__dirname)
  .filter(file => {
    return (file.indexOf('.') !== 0) && (file !== basename) && (file.slice(-3) === '.js');
  })
  .forEach(file => {
    const model = require(path.join(__dirname, file))(sequelize, Sequelize.DataTypes);
    db[model.name] = model;
  });

Object.keys(db).forEach(modelName => {
  if (db[modelName].associate) {
    db[modelName].associate(db);
  }
});

db.sequelize = sequelize;   //sequelize, Sequelize 두가지 속성 값을 db에 넣었다. 
db.Sequelize = Sequelize;

module.exports = db; // db라는 변수를 결과적으로 넘기는구나 
//db라는 파일을 불러왔을 때 객체로 받는구나 알 수 있음.
//팁 : 얘는 결국 무엇을 넘기나 아랫줄에 module을 쳌! 그거에 대한 결과값이 무엇인가 
//무언가를 담아서 보냈는가 를 쳌 

 

 

 

models - index.js에서 실질적으로 쓸 부분 

 

'use strict';

 

const fs = require('fs');

const path = require('path');

const Sequelize = require('sequelize');

const basename = path.basename(__filename);

const env = process.env.NODE_ENV || 'development';

const config = require(__dirname + '/../config/config.json')[env];

const db = {};

 

let sequelize;

if (config.use_env_variable) {

  sequelize = new Sequelize(process.env[config.use_env_variable], config);

} else {

  sequelize = new Sequelize(config.database, config.username, config.password, config);

}

fs

  .readdirSync(__dirname)

  .filter(file => {

    return (file.indexOf('.') !== 0) && (file !== basename) && (file.slice(-3) === '.js');

  })

  .forEach(file => {

    const model = require(path.join(__dirnamefile))(sequelizeSequelize.DataTypes);

    db[model.name] = model;

  });

 

Object.keys(db).forEach(modelName => {

  if (db[modelName].associate) {

    db[modelName].associate(db);

  }

});

 

db.sequelize = sequelize;

db.Sequelize = Sequelize;

 

module.exports = db;

 

 

 

 

3. config.json 파일 안 development 내용을 나의 컴퓨터 mysql 정보로 바꾸기 

{
  "development": {
    "username": "root",
    "password": "d",      //비밀번호 변경
    "database": "joinn",  //table을 생성할 database명 입력 (새거or 기존 상관없이 새로운table을 만듬) 
    "host": "127.0.0.1",
    "dialect": "mysql"
  },

 

 

 

4. Sequelize를 통해 express  app과 mySQL 연결하기 

app.js 파일 만들고 코드 작성 (서버 실행할 때 쓸 server JS) 

 

const express=require('express');
const app = express();
const {sequelize}=require('./models'); // 이 부분 추가 

app.get('/', (req,res)=>{
    res.send('hello');
})

app.listen(3000,()=>{
    console.log('server start : 3000')
})

기본 express 서버 구조에 

const sequelize = require('./models') 요 부분 추가 -> models 파일 안 index를 가져와서 sequelize 변수에 넣었다. 

 

* 변수 명이 sequelize가 아닌 {sequelize}인 이유

models - index.js 파일을 가져오면 db를 가져오는데 그 결과값을 선택해서 가져오겠다. 

질문:  {sequelize} 하면 sequelize가 아닌 Sequelize객체를 가져옴 

 

sequelize 만 쓰고 console.log를 찍으면 Sequelize, sequelize 부분ㅇ ㅣ 쭉 - 나옴 

 

 

 

 

5. Sequelize db접속 하기 / DB접속 server test code 작성

작성 후, 터미널에 node app.js 입력 -> db 성공 / 실패 check 

const express=require('express');
const app = express();
const {sequelize}=require('./models'); // models - index.js 가져온다. 

sequelize.sync({force:false})              // 추가 
.then(()=>{
    console.log('db접속 성공')
})
.catch(()=>{
    console.log('db접속 실패')
})

app.get('/', (req,res)=>{
    res.send('hello');
})

app.listen(3000,()=>{
    console.log('server start : 3000')
})

code 분석 

sequelize.sync({force:false})    

sequelize = 객체 , .sync ( ) method를 사용함 .sync( )의 결과값은 new Promise 객체 -> .then, .catch 사용 가능 

force: false : 접속했을 때 table이 존재하는가 안하는가에 따라 table을 새로 만들지를 세팅해주는 부분 

force: true = > 생성하지않음 / force:true => 생성함

 

 

 

5. User model 정의하기    (models 폴더 -> user.js 파일 생성 및 코드 작성 )  

 node.js 교과서 개정2판 320p 내용 작성 

sequelize는 보통 table명은 복수형, model 이름은 단수형으로 쓴다. 

sequelize는 model과 mySQL의 table을 연결해 주는 역할 

 

user.js 파일 작성 

const Sequelize=require('sequelize');  //sequelize가져오기 

module.exports=class User extends Sequelize.Model{  //class 던져주기 
    static init(sequelize){
        //User라는 class에서 정적으로 사용하는 , 쉽게 말하면constructor 
        //처음 생성할 때 요기가 실행된다~ 
        //User라는class가 객체 생성없이 바로 사용 가능하다~ 라는 뜻
        return super.init({  // super : 부모에 있는 method 가져옴 / 부모의 init이라는 method가져옴 
            name:{ //name varchar(20) NOT NULL UNIQUE
                type:Sequelize.STRING(20), //부모로부터  받아 Sequelize.STRING 이라고 적기 
                                            //== varchar(20) 
                allowNull:false,  // == not null 무적권 이름은 null값이 있으면 안된다. 
                unique:true,    // unique 사용하겠다 ~ 
            },
            age:{ // age라는 field를 만들거고  sql 구문 = age INT UNSIGNED NOT NULL 
                type:Sequelize.INTEGER.UNSIGNED, // 숫자만 사용할건데 양수만 사용할거야 + 값만 
                allowNull:false, // NOT NULL 
            },
            married:{  // married TINYINT(1) NOT NULL 
                type:Sequelize.BOOLEAN, // tinyint 한자리수 정수 숫자 받는 뜻
                allowNull:false, //not null
            },
            comment:{ /// comment TEXT NOT NULL 
                type:Sequelize.TEXT,
                allowNull:true,
            },
            created_at:{ // created_at DATETIME NOT NULL default NOW()
                type:Sequelize.DATE,
                allowNull:false,
                defaultValue:Sequelize.NOW,
            },
        },{
            sequelize,// 사용할 때 인자값 내용 넣는거 
            timestamps:false, // true 하게 되면 createdAt과 updatedAt columns 자동 추가함 
            underscored:false, // true하면 camel case -> snake case 로 전환하게됨(영문대소문자)
            modelName:'User', // express에서 JS 사용하기위한 이름 설정
            tableName:'users', // 실제 table 이름 요걸로 사용하겠다. 
            paranoid:false, // true 하면 deletedAt column생김 row 삭제할 때 완전히 지워지지않고
            //지워진 시각 기록 -> row 조회 명령 시 deletedAt column value = Null값만 불러와짐 
            // 삭제한 row 복원하고 싶다면 true! 
            charset:'utf8',  //한글 입력 가능하게 utf8mb4 쓰면 이모티콘도 가능 
            collate:'utf8_general_ci', //or utf8mb4쓰기 
        });
    }
    static associate(db){} // 아직은 사용안함 
};

 

 

index.js 수정

'use strict';

const fs = require('fs');
const path = require('path');
const Sequelize = require('sequelize');
const basename = path.basename(__filename);
const env = process.env.NODE_ENV || 'development';
const config = require(__dirname + '/../config/config.json')[env];
const User = require('./user'); //result = class / user.js 가져옴 

const db = {};

let sequelize;
if (config.use_env_variable) {
  sequelize = new Sequelize(process.env[config.use_env_variable], config);
} else {
  sequelize = new Sequelize(config.database, config.username, config.password, config);
}

db.User=User;//app.js에서 User라는 class 가져올 수 있도록 db객체에 User property넣음 

User.init(sequelize);


db.sequelize = sequelize;
db.Sequelize = Sequelize;

module.exports = db;

 

app.js  force:true로 변경 

const express=require('express');
const app=express();
const {sequelize} = require('./models')

sequelize.sync({force:true});

app.get('/',(req,res)=>{
    res.send('hello');
})

app.listen(3000,()=>{
    console.log('server start : 3000')
})

 

-> node app.js 실행 하고 아래 읽어보기 

mySQL prompt 창에 가서 show tables 해보면

 

요렇게 jonn이라는 기존에 있었던 database에 2번째 새로운 table 'users'를 만들었다. 

 

 

 

 

 

 

그리고 fields도 만들어졌다. 

 

 

 

 

 

 

 

 

 

 

---> table 만들었으니 app.js 의 force:false로 다시 변경하기 

sequelize.sync({force:false});

 

 

 

 

 

6. 생성한 table안에 DB 추가 = SQL명령  insert  해보기

 

app.js 에 User.create문구 (SQL insert into구문 넣기) 

const express=require('express');
const app=express();
const {sequelize, User} = require('./models')

sequelize.sync({force:false});

app.get('/',(req,res)=>{
    User.create({
        name:'zero',
        age:'24',
        married:false,
        comment:'자기소개1',
    })

    res.send('hello');
})

app.listen(3000,()=>{
    console.log('server start : 3000')
})

 -> 터미널에 app.js 키고 -> localhost:3000 브라우저에 새로고침하고 -> 다시 mysql 보면

내용이 잘 들어갔다. 

 

 

 

 

 

 

* 이 부분도 삭제 가능

sequelize.sync({force:false});

 

 

7. 생성한 table 안에 Select문 해보기 

 

 

먼저 console.log로 User.findAll({}) 결과값 확인 해보기

const express=require('express');
const app=express();
const {sequelize} = require('./models')
const {User} = require('./models');

app.get('/',(req,res)=>{
    
    /*User.create({
        name:'zero',
        age:'24',
        married:false,
        comment:'자기소개1',
    })*/
    console.log(User.findAll({}));

    res.send('hello');
})

app.listen(3000,()=>{
    console.log('server start : 3000')
})

 

결과가 Promise 객체로 떨어짐을 알 수 있다. 

 

 

async & await 넣어서 console.log 찍어보기 

const express=require('express');
const app=express();
const {sequelize} = require('./models')
const {User} = require('./models');

app.get('/', async (req,res)=>{
    
    /*User.create({
        name:'zero',
        age:'24',
        married:false,
        comment:'자기소개1',
    })*/
    console.log(await User.findAll({}));

    res.send('hello');
})

app.listen(3000,()=>{
    console.log('server start : 3000')
})

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

배열, 객체로 담아서 나온다. => User.findAll({}) -> 비동기임을 알 수 있음-결과가 Promise 객체 값이므로 

 

 

변수에 담아서 특정 값 가져와보기 

const express=require('express');
const app=express();
const {sequelize} = require('./models')
const {User} = require('./models');

app.get('/', async (req,res)=>{
    
    /*User.create({
        name:'zero',
        age:'24',
        married:false,
        comment:'자기소개1',
    })*/
    const userList = await User.findAll({})
    console.log(userList[0].name); 
    
    res.send('hello');
})

app.listen(3000,()=>{
    console.log('server start : 3000')
})

name값 : zero1 가져옴

 

 

 

name, married만 뽑아오기 

 

const express=require('express');
const app=express();
const {sequelize} = require('./models')
const {User} = require('./models');           //질문 -> 요기 파일은 index? of user?

app.get('/', async (req,res)=>{
    /*User.create({
        name:'zero',
        age:'24',
        married:false,
        comment:'자기소개1',
    })*/
    const userList = await User.findAll({
        attributes:['name','married']
    })
    res.send('hello');
})

app.listen(3000,()=>{
    console.log('server start : 3000')
})

 

 

 

이 외의 구문 skill은 node.js 교과서 개정2판 230-231p 참고

 

 

 

 

 

 

-------------------------------------------------------여기까지가 Models 부분 ------------------------------------------------

-----------------------------------------------------------------------------------------------------------------------------------

 

 

 MVC  

Model

- Data를 받고 저장, DB에 있던 내용, 내가 사용할 DB를 객체로 저장하는 곳 

- 데이터를 저장한 객체 - > 요 Data 가지고 모든걸 표현할 수 없다. ex) 게시판의 paging etc. => 이 때 controller가 필요한 logic을 추가해서 view로 보낸다.  

-> Data가 뭔가 잘못된거 같다싶으면 model 쪽 체크 

 

View 

- 화면에 뿌려주는 , 실질적으로 Client가 보는 부분 

- nunjucks의 활용, nunjucks를 쓰면 MVC 패턴 중 view부분 

-> 뭔가 화면이 이상하면 view 쪽 체크 

 

Controllers 

- model에서 받은 걸 조작해서 view로 보냄 (model & view를 연결하는 곳) 

- 최소한의 코드들만 따로 뽑아서 business logic 만 처리할 수 있게 만든게 controllers 

-> paging이 이상하면 controllers 쪽 체크 

 

 

 

-----------------------------------------------------------------------------------------------------------------------------------

 

 

 

 

8. ROUTER  + nunjucks 추가, views 폴더 - index.html 등 폴더& 파일들 추가 작업

 

app.js 에 nunjucks 추가

const nunjucks = require('nunjucks');

nunjucks.configure('views',{
    express:app,
})

app.set('view engine','html');

nunjucks에서 views 폴더에 있는걸 사용하겠다고 했으니 views 폴더 + index.html 추가 

 

 

 

router 폴더 만들기 

router 폴더 안 index.js 파일 만들기

router 폴더 안 main 폴더 만들기 - 그 안에 index.js 파일 만들기 

 

 

 

 

app.js

const express=require('express');
const app=express();
const {sequelize} = require('./models')
const {User} = require('./models');
const nunjucks = require('nunjucks');
const indexRouter=require('./router');               //indexRouter는 router - index.js이다. 

nunjucks.configure('views',{
    express:app,
})
app.set('view engine','html');   

app.use('/', indexRouter);          //   '/'를 받으면 indexRouter 로 가라 

app.listen(3000,()=>{
    console.log('server start : 3000')
})

 

router-index.js 

const express = require('express');
const router=express.Router();
const mainRouter=require('./main/index.js'); // mainRouter는 main - index.js 이다. 

router.use('/',mainRouter);     //   '/'를 받으면 mainRouter 로 가라 

module.exports = router;

 

router-main-index.js

const express = require('express');
const router = express.Router();

router.get('/',(req,res)=>{
    res.render('index.html');          // index.html (views폴더 안) 을 render해라 
})

module.exports=router;

 

 

app.js 에서 '/'을 받으면 indexRouter (router-index.js) -> router-index.js에서 '/'을 받으면 mainRouter (router-main-index.js) -> router-main-index.js에서 '/' 을 받으면 res.render('index.html') -> views - index.html 열림 

 

 

 

 

 

 

9. business logic Controllers 부분 나누기

 

router-main - index.js (index.html render해주는 마지막 js 파일 )

const express = require('express');
const router = express.Router();
const controller = require('./main.controller');

router.get('/',controller.main)

module.exports=router;

 

main폴더에 main.controller.js 파일 만들기

 

main.controller.js

const {User} = require('../../models')

let main = async (req,res) =>{
    let user = await User.findAll({})         // 요 줄의 의미? 질문
    res.render('index.html')
}

exports.main=main;
//  보낼 명 // 보낼 함수 

 

 

 

router - index.js     /board 내용 추가 

const express = require('express');
const router=express.Router();
const mainRouter=require('./main/index.js');
const boardRouter=require('./board/index');             //이 부분 만들기 

router.use('/',mainRouter);
router.use('/board',boardRouter);

module.exports = router;

 

 

router - board 폴더 생성 - index.js 파일 만들기 

 

router-board-index.js

const express = require('express');
const router=express.Router();
const controller = require('./board.controller');      //이 파일 만들기 

router.get('/list', controller.list);
router.get('/view', controller.view);
router.get('/write', controller.write);
router.get('/modify', controller.modify);

module.exports=router;

 

router - board - board.controller.js 파일 만들기 

let list = (req,res)=>{
    res.render('list.html');
}

let view = (req,res)=>{
    res.render('view.html');
}

let write = (req,res)=>{
    res.render('write.html');
}

let modify = (req,res)=>{
    res.render('modify.html');
}

module.exports={
    list:list,
    view:view,
    write:write,
    modify:modify
}

 

이제 views 폴더 안에 list, view, write, modify 파일 만들기

 

modify.html입니다. 

 

->node app.js 실행 -> localhost:3000 & 3000/board/list, write, view, modify 확인 

 

 

 

 

 

 

 

routers- board - board.controller.js 에  async , await 적용

const {User} = require('../../models')
//요걸 가져오면 



let list = async (req,res)=>{
    //select 
    let UserList = await User.findAll({})
    res.render('list.html')
}

let view = (req,res)=>{
    //select
    let UserList = await User.findAll({})
    res.render('view.html')
}

//board/write POST 
let write = (req,res)=>{
    //insert
    let rst = await User.create({
        //....req 요청값에 나왔던 부분을 넣어주면 됨
    })
    res.render('write.html')
}

let modify = (req,res)=>{
    //update
    let rst = await User.update({
        //필드 : '바뀔내용'..
    },{
        where: { //필드:값}                   이런 nunjucks의 결과를 떤져주면됨
    })
    res.render('modify.html')
}

module.exports={
    list:list,
    view:view,
    modify:modify,  //modify 라는 속성값을 modify 라는 method로 
    write:write
}

 

 

 

 

 

 

 

 

 

----------------------------------------------------------------------------------------------------------------------------------

 

 

 

질문 이부분이 잘 이해가 안감 

class test{
    constructor(){
        this.name="a"
    }

    init(){
        console.log('29');
    }

    static init(){
        this.age="20"
        console.log('50');
    }
}

console.log(test);
console.log(new test);
test.init();

let a = new test();

a.init();

 

 

 

 

 

반응형