웹 개발

[포스코X코딩온] Sequelize 실습

끊임없이 성장중인 개발자 2023. 12. 13. 13:29
728x90
반응형

포스팅 주제

  • Sequelize 실습

이번 실습에서는 이전에 만든 MVC로그인 실습을 sequelize로 만드는 실습이다.

 

 

먼저 sequelize를 구성하는 폴더부터 설정해 주었다.

< config - config.json >

{
    "development": {
        "username" : "user",
        "password" : "1234",
        "database" : "kdt",
        "host" : "127.0.0.1",
        "dialect" : "mysql"
    },
    "production" : {},
    "test" :{}
}

 

< app.js >

const express = require('express');
const app = express();
const PORT = 8000;

const db = require('./models/index');

app.set('view engine', 'ejs');
app.set('views', './views');

app.use('/static', express.static(__dirname + '/static'));

app.use(express.urlencoded({extended: true}));
app.use(express.json());

// // 라우터 분리
const indexRouter = require('./routes/index');
app.use('/', indexRouter);


// 애러 처리
app.get('*', (req,res) => {
    res.render('404');
})

db.sequelize.sync({force: false}).then(() => {

    //force: false => 테이블이 없으면 생성
    //force: true => 테이블 무조건 생성(만약 db가 있다면 삭제하고 다시 생성 -> prod에서 사용 x [사용자 정보 손실] )

    app.listen(PORT, () => {
        console.log(`${PORT} is opening!!`)
    })
})

 

< models - index.js >

const Sequelize = require('sequelize');
const config = require(__dirname + '/../config/config.json')['development'];

const db = {};

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

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

db.User = require('./User')(sequelize, Sequelize);

module.exports = db;

 

sequelize를 사용하기 위해서 sequelize와 DB를 설정해준다.

 

< models - User.js >

const User = (Sequelize, DataTypes) => {
    const model = Sequelize.define(
        'user',
        {
            id: {
                type: DataTypes.STRING(10),
                allowNull:false,
                primaryKey:true
            },
            pw : {
                type: DataTypes.STRING(10),
                allowNull:false
            },
            name: {
                type: DataTypes.STRING(5),
                allowNull: false
            }
        },
        {
            tableName: 'user2',
            freezeTableName:true,
            timestamps:false
        }
    )
    return model
}
module.exports = User;

 

DB를 사용하기 위해서 DB를 설정해준다.

User라는 이름을 가진 모델을 사용할 것이다.

id

  • type: DataType.STRING(10)
  • allowNull: false
  • primaryKey: ture

pw

  • type: DataType.STRING(10)
  • allowNull : false

name

  • type: DataType.STRING(5)
  • allowNull: false

 

테이블 이름(tableName)은 'user2', 타임스탬프는 false로 설정했다.

module.exports = User; 다른 곳에서 User라는 이름으로 접근할 수 있게 module.exports 해준다.

 

< controller - Cuser.js >

const models = require('../models/index');
const User = models.User;

exports.main = (req,res) => {
    res.render('index');
}

//db에러 처리는 .catch로 만들면 된다.( 사이트 죽이지 않게 )

// 가입화면 표시
exports.singup = (req,res) => {
    res.render('singup');
}
// 가입 post
exports.singup_new = (req,res) => {
    // 뷰(요청) -> 라우터 -> 컨트롤러 -> 모델 -> DB -> 모델 -> 컨트롤러 -> 뷰(응답)
    console.log('req.body >>> ', req.body);
    const{id, pw, name} = req.body;

    // [before]
    // User.postDB(req.body, (result) => {
    //     console.log('psotDB, Cuser.js result >>',result);
    //     if(result.error){
    //         res.send({isLogin:false})
    //     }else{
    //         res.send({isLogin:true, id: id, pw: pw, name: name});
    //     }
    //     // res.send({id: id, pw: pw, name: name});
    // })
    // [after]
    User.findOne({
        where: {
            id : id
        }
    }).then((result) =>{
        console.log('id duplicate >', result);
        if(result!==null) {
            res.send({isLogin:false});
        }else{
            console.log('else');
            User.create({
                id: id,
                pw: pw,
                name: name
            }).then((result)=>{
                console.log('then >', result)
                res.send({isLogin:true});
            })
        }
    })
}

// 로그인
exports.singin = (req,res) => {
    res.render('singin');
}
exports.sigin_check = (req, res) => {
    console.log('req.body >' , req.body)

    //[before]
    // User.postCheck(req.body, (result) => {
    //     // result:rows
    //     if(result.length > 0 ) res.send({isLogin:true,userInfo:result[0]});
    //     else(res.send({isLogin:false}))
    // })

    //[After]
    // SELECT id,pw FROM user WHERE id = ? AND pw = ?"
    User.findAll(
    {
        attributes: ['id', 'pw'],
        where: {
            id : req.body.id,
            pw: req.body.pw
        }
    }
    ).then((result) => {
        console.log('findOne result >>',result);
        if(result.length > 0){
            res.send({isLogin:true})
        }else{
            res.send({isLogin:false})
        }

        //result
        //id, pw 일치 : {}
        //불일치 : null
    })
    
}

// 프로필 수정(id값 가져오기)
exports.profile = (req,res) => {
    console.log(req.body);

    //[before]
    // User.get_user(req.body.id, (result) =>{
    //     if(result.length > 0) res.render('profile', {data: result[0]})
    // })

    //[After]
    //"SELECT * FROM user WHERE id = ?"
    User.findOne({
        // User.findAll({
        // raw:true,
        where: {
            id : req.body.id
        }
    }).then((result)=>{
        // console.log('RESULT!!!!!!! >>> ',result);
        // res.render('profile',{data:result[0]});

        if(result){
            res.render('profile',{data:result})
        }
    })

    // console.log(req.body.id);
    // res.render('profile', {fixid:req.body.id});
}

// 프로필 수정 2 (회원 정보 수정)
exports.profileEdit = (req,res) => {
    //[Before]
    // User.profileChange(req.body, (result) => {
    //     console.log('바꿀 정보 > ', req.body);
    //     console.log('화원 정보 수정 > ', result);
    //     res.send('수정 성공');
    // })

    //[After]
    User.update({
        pw : req.body.pw,
        name : req.body.name
    },{
        where: {
            id : req.body.id
        }
    }).then((result)=>{
        console.log('update > ', result);
        res.send('수정성공');
    })
}

// 프로필 삭제
exports.profileDelete = (req, res) => {
    console.log(req.body);

    //[Before]
    // User.delete_profile(req.body.id, (result) => {
    //     res.send({deletedId : req.body});
    // })

    //[After]
    User.destroy({
        where: {
            id: req.body.id
        }
    }).then((result)=>{
        res.send('삭제성공');
    })
}

 

회원가입

=> findOne()으로 DB에서 해당하는 아이디값을 확인해서 존재하지 않으면 null값 보내고, 존재한다면 해당 아이디 값을 보낸다.

아이디가 존재한다면 isLogin:false를 보내고, 아니면 회원 생성 SQL문(create)을 실행한다.

생성 후 isLogin:true를 반환한다.

 

로그인

=> login()에서 입력된 값들을 DB에서 검색해서 있다면 값이 반환되고 없다면 반환되지 않을것이다, 이를 가지고 값이 있다면 isLogin:true를 없다면 false를 반환한다.

 

프로필 보여주기

=> login()에서 hidden-form으로 받은 id값을 가지고 프로필을 DB에서 찾아서 해당 값을 profile.ejs에 data값으로 넘겨준다.

프로필에서는 <%= data.id %> 형식으로 값을 가져와서 사용한다.

 

프로필 수정

=> 프로필에 입력된 값을 가지고 Edit()버튼을 클릭시 DB에서 해당하는 id값의 db를 찾아서 pw, name만 변경해준다.

 

프로필 삭제

=> 입력받은 id값을 가지고 DB를 검색해서 해당 데이터를 삭제한다.

 

< static - user.js >

// 회원가입 버튼
function singUP(){
    const form = document.forms['newUser'];

    if(!form.checkValidity()){
        form.reportValidity();
        return;
    }

    axios({
        method: 'post',
        url: '/user/singup',
        data: {
            id : form.id.value,
            pw : form.pw.value,
            name: form.name.value
        }
    }).then((res) => {
        console.log('res.data >> :', res.data);
        const {data} = res;

        if(!data.isLogin){
            alert('이미 존재하는 회원입니다! 아이디를 확인해주세요 :)');
            form.reset(); // form 초기화
        }else{
            alert('회원가입 성공');
            document.location.href = '/user/singin';
        }
    })
}

// 로그인 버튼
async function login(){
    const form = document.forms['logIn'];
    
    if (!form.checkValidity()) {
        form.reportValidity();
        return;
    }

    try{
        let res = await axios({
            method: 'post',
            url: '/user/singin',
            data: {
                id : form.id.value,
                pw: form.pw.value
            }
        })
        console.log(res.data)
        const { data } = res;

        if(data.isLogin){
            alert('로그인 성공')
            
            //프로필 페이지 요청 보내기
            const form_info = document.forms['hidden-form'];
            form_info.id.value = form.id.value;
            form_info.submit()
        } else{
            alert('로그인 실패!');
            form.reset();
        }
    }
    catch(err){
        console.log(err);
    }
}

// 회원정보 변경
function Edit(){
    const form = document.forms['PROFILE'];

    if(!form.checkValidity()){
        form.reportValidity();
        return;
    }

    axios({
        method: 'patch',
        url: '/user/profile/edit',
        data : {
            id: form.id.value,
            pw: form.pw.value,
            name: form.name.value
        }
    }).then((res) => {
        console.log(res);
    })
}

//아이디 삭제
function Delete(){
    const form = document.forms['PROFILE'];

    if(!form.checkValidity()){
        form.reportValidity();
        return;
    }

    axios({
        method: 'delete',
        url: '/user/profile/delete',
        data:{
            id: form.id.value
        }
    }).then((res) => {
        console.log(res);
        alert('회원 탈퇴 성공!');

        //회원 탈퇴 했으면 프로필 페이지 x => 메인 페이지로 이동
        document.location.href = '/user';
    }).catch((err) => {
        console.log(err);
    })
}

 

회원가입(singUp) 버튼

=> 입력한 값을 DB로 보내 체크 후 isLogin을 반환 받는다. 이 값을 통해 false면 alert문을, true면 alert문과 페이지 이동을 한다.

 

로그인(login)버튼

=> 로그인 버튼 클릭시 입력받은 데이터 값을 Cuser로 보내서 DB를 검색한다. 반환 값으로, 값이 있다면 isLogin:true, 없다면 isLogin:false를 반환 받는다.

해당 값을 가지고 if문을 사용한다, true라면 alert('로그인 성공')을 띄워주고 숨겨진 form(hidden-form) input에 아이디 값을 부여해서 전송한다.

회원정보 변경(Edit) 버튼

=> 입력된 정보를 controller에 전송하여 DB를 검색해서 변경한다.

 

회원정보 삭제(Delete) 버튼

=> 입력한 정보를 전송하여 DB를 찾아서 삭제한다, 만약 성공한다면 document.location.hraf를 사용하여 홈페이지로 이동한다.

 

< routes - user.js >

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

const controller = require('../controller/Cuser');

// GET /user
router.get('/', controller.main);

// GET /user/singup
router.get('/singup',controller.singup)
//post
router.post('/singup', controller.singup_new);

// GET /user/singin => post
router.get('/singin', controller.singin);
// POST /user/singin
router.post('/singin', controller.sigin_check);

// POST /user/profile
router.post('/profile', controller.profile);
// PATCH /user/profile/edit
router.patch('/profile/edit', controller.profileEdit);
// DELETE /user/profile/delete
router.delete('/profile/delete', controller.profileDelete);

module.exports = router;

 

views 폴더의 내용들은 이전 포스팅 내용과 같기 때문에 생략하겠습니다.

반응형