jnk1m
Foliage IT
jnk1m
전체 방문자
오늘
어제
  • 분류 전체보기 (209)
    • Today I Learned (34)
    • Java (47)
    • Database (15)
    • [NHN Academy] (27)
    • Spring (47)
    • HTML + CSS + JavaScript (11)
    • JSP (3)
    • Node.js (10)
    • React Native (2)
    • 기타 (8)
    • 스크랩 (5)

인기 글

최근 글

티스토리

hELLO · Designed By 정상우.
글쓰기 / 관리자
jnk1m

Foliage IT

Node.js

[Node.js] Day 08: 데이터 가져와서 출력하기2

2022. 5. 13. 01:26

3)데이터 삽입 요청을 처리하는 코드를 index.js에 추가

//데이터 삽입 화면 출력 요청
app.get('/item/insert',(req,res,next)=>{
    //퍼블릭 디렉토리에 있는 insert.html 파일을 비동기적으로 읽어서
    //에러가 발생하면 에러 내용을 err에 저장하고 그렇지 않으면
    //읽은 내용을 data에 저장 
    fs.readFile('public/insert.html',(err,data)=>{
        //문자열로 전송
        res.end(data);; //읽은 데이터를 여기서 그대로 리턴
    })
})

//데이터 삽입 요청: 파일 한개 업로드 포함
app.post('/item/insert',upload.single('pictureurl'),(req,res,next)=>{
    //클라이언트가 전송한 데이터를 가져오기
    const itemname = req.body.itemname; 
    const description = req.body.description;
    const price = req.body.price;

    var pictureurl;
    if(req.file){
        pictureurl = req.file.filename;
    }else{
        pictureurl= "default.png"
    }

//가장 큰 itemid를 조회해서 다음 itemid를 생성
connection.query('select max(itemid) maxid from goods',
    (err,results,fields)=>{
        if(err){
            throw err;
            console.log(err);
        }
        var itemid;
        if (results.length > 0){
            itemid = results[0].maxid+1
        }else{
            itemid = 1;
        }

        //삽입하는 날짜 (현재 날짜 및 시간)을 생성
        var date = new Date();
        var year = date.getFullYear();
        var month = date.getMonth()+1;
        month = month >= 10? month: '0'+month;
        var day = date.getDate();
        day = day >= 10 ? day : '0'+day; 
        var hour = date.getHours();
        hour =  hour >= 10 ? hour : '0'+hour; 
        var minute = date.getMinutes();
        minute =  minute >= 10 ? minute : '0'+minute; 
        var second = date.getSeconds();
        second =  second >= 10 ? second : '0'+second; 

        connection.query(
            'insert into goods(itemid, itemname, price, description, pictureurl, updatedate) values(?,?,?,?,?,?)', 
            [itemid, itemname, price, description, pictureurl, year+'-'+month+'-'+day],
            (err, results, fields)=>{
                console.log(err);
                if(results.affectedRows==1){//삽입 성공하면 레코드가 한줄 추가됨 -> 영향받은 행의 개수가 1개
                    //데이터를 삽입한 시간을 update.txt에 기록
                    const writeStream = fs.createWriteStream('./update.txt')
                    writeStream.write(year+'-'+month+'-'+day+'-'+hour+'-'+minute+'-'+second)
                    writeStream.end();

                    res.json({'result':true})
                }else {
                    res.json({'result':false})
                }
            })

})

})



4)index.html 파일에서 데이터 삽입 요청을 위한 메뉴를 생성
<a href="#" id="insertbtn">데이터 삽입</a>



5)index.html 파일에서 데이터 삽입 요청을 위한 스크립트를 생성

       document.getElementById("insertbtn").addEventListener(
            'click', (e) =>{
                var request = new XMLHttpRequest();
                request.open('GET', '/item/insert')
                request.send('')
                request.addEventListener('load', () => {
                    //데이터 출력 영역 초기화
                    content.innerHTML = "";
                    updatearea.innerHTML = request.responseText;

                    //폼을 찾아오기
                    var f = document.getElementById("insertform");
                    if(f != undefined){
                        f.addEventListener('submit', (e) => {
                            //기본 이벤트 제거 - form 데이터를 submit 하지 않음
                            e.preventDefault();

                            //폼의 데이터 가져오기
                            const formData = new FormData(f);

                            //폼의 데이터를 전송. 삽입이니까 get을 보내면x
                            var xhr = new XMLHttpRequest();
                            xhr.open("POST", "/item/insert", true);
                            xhr.send(formData);

                            xhr.addEventListener('load', () => {
                                var data = JSON.parse(xhr.responseText);
                                if(data.result){
                                    //목록보기 실행
                                    document.getElementById('listbtn').click();
                                    updatearea.innerHTML = '';
                                }else{
                                    alert("삽입 실패")
                                }
                            })

                        })
                    }
                })
        })



17.데이터 삭제
1)index.js 파일에 삭제를 위한 라우팅 함수를 작성

app.post('/item/delete', (req, res, next) => {
    //파라미터 읽어오기: 삭제는 기본키 만을 읽어옵니다.
    //클라이언트에서는 itemid 라는 이름으로 itemid를 post 방식으로 전송
    const itemid = req.body.itemid;

    //삭제하는 날짜(현재 날짜 및 시간)를 생성
    var date = new Date();
    var year = date.getFullYear();
    var month = date.getMonth() + 1;
    month = month >= 10 ? month : '0' + month;
    var day = date.getDate();
    day = day >= 10 ? day : '0' + day
    var hour = date.getHours();
    hour = hour >= 10 ? hour : '0' + hour;
    var minute = date.getMinutes();
    minute = minute >= 10 ? minute : '0' + minute;
    var second = date.getSeconds();
    second = second >= 10 ? second : '0' + second;

    connection.query('delete from goods where itemid = ?',
    [itemid], (err, results, next) => {
        //에러 내용 확인
        if(err){
            console.log(err)
        }

        if(results.affectedRows >= 0){
            //데이터를 삭제한 시간을 update.txt에 기록
            const writeStream = fs.createWriteStream('./update.txt');
            writeStream.write(year + '-' + month + '-' + day + ' ' + 
            hour + ':' + minute + ':' + second);
            writeStream.end();

            res.json({"result": true});
        }else{
            res.json({"result": false});
        }

    })

})



2)index.html 파일의 상세보기 스크립트 코드를 수정

      //출력 내용 상세보기
       content.addEventListener('click', (e) => {
            //실제로 클릭이 발생한 항목의 id 가 item으로 시작할 때만
            if(e.target.id.startsWith('item')){
                //itemid 만 추출 - item 이라는 4글자를 제외하고
                var itemid = e.target.id.substring(4).trim();
                
                var request = new XMLHttpRequest();
                request.open('GET', '/item/detail?itemid=' + itemid);
                request.send("");
                request.addEventListener('load', () => {
                    //자바스크립트의 데이터로 변환
                    var data = JSON.parse(request.responseText);

                    //출력 영역 초기화
                    updatearea.innerHTML = '';
                    content.innerHTML = '';

                    //출력 내용 만들기
                    var display = "";
                    display += "<div align='center' class='body'>";
                    display += "<h2>상품 상세 화면</h2>";

                    //데이터가 있다면
                    if(data.result == true){
                        var item = data.item;

                        display += "<table>";
                        display += "<tr><td>";
                        display += "<img height='100' width='100' src='/img/";
                        display += item.pictureurl + "'><td>";

                        display += "<td align='center'><table>";
                        
                        display += "<tr height='50'><td width='80'>";
                        display += "상품명</td>";
                        display += "<td width='160'>" + item.itemname;
                        display += "</td></tr>";

                        display += "<tr height='50'><td width='80'>";
                        display += "가격</td>";
                        display += "<td width='160'>" + item.price;
                        display += "원</td></tr>";

                        display += "<tr height='50'><td width='80'>";
                        display += "비고</td>";
                        display += "<td width='160'>" + item.description;
                        display += "</td></tr>";

                        display += "<tr height='50'>";
                        display += "<td colspan='2' align='center' width='240'>";
                        display += "<a href='#' id='mainbtn'>목록보기</a>"
                        display += "</td></tr>";

                        display += "<tr height='50'>";
                        display += "<td colspan='2' align='center' width='240'>";
                        display += "<a href='#' id='deletebtn'>데이터 삭제</a>"
                        display += "</td></tr>";
                        

                        display += "</table>"



                    }else{
                        display += "<p>데이터가 존재하지 않습니다.</p>";
                    }
                    content.innerHTML = display;

                    var mainbtn = document.getElementById("mainbtn");
                    if(mainbtn != undefined){
                        mainbtn.addEventListener('click', (e) => {


                            document.getElementById('listbtn').click()
                        })
                    }

                    var deletebtn = document.getElementById("deletebtn");
                    if(deletebtn != undefined){
                        deletebtn.addEventListener('click', (e) => {
                            var request = new XMLHttpRequest();
                            request.open('POST', '/item/delete', true);

                            //폼이 없고 파일이 없는 상태의 POST 방식 파라미터 만들기
                            var params = "itemid=" + data.item.itemid;
                            request.setRequestHeader('Content-type',
                            'application/x-www-form-urlencoded');
                            request.send(params);

                            request.addEventListener('load', ()=>{
                                var data = JSON.parse(request.responseText);
                                if(data.result){
                                    document.getElementById("listbtn").click();    
                                }else{
                                    alert("삭제 실패");
                                }
                            })

                        })
                    }



                })

            }
        })


       
18.데이터 수정
1)데이터 수정 화면으로 update.html 파일을 public 디렉토리에 생성하고 작성

<div>
    <form method='post' id='updateform' enctype='multipart/form-data'>
        아이템 id<input type='text' name='itemid' id='itemid'/>
        <br/>
        아이템 이름<input type='text' name='itemname' id='itemname'/>
        <br/>
        아이템 가격<input type='text' name='price' id='price'/>
        <br/>
        설명<textarea name='description' id='description'></textarea>
        <br/>
        새로운 이미지<input type='file' name='pictureurl' id='pictureurl'/>
        <br/>
        이전 이미지<img width="100" height="100" id="picture" /><br/>
        <input type="hidden" name="oldpictureurl" id="oldpictureurl"/>
        <input type='submit' value='수정'/>
    </form>
</div>



2)index.js 파일에 데이터 수정 요청을 하면 update.html 파일의 내용을 읽어서 리턴하는 라우팅 함수를 작성

//수정 요청 처리
app.get("/item/update", (req, res, next) => {
    fs.readFile('public/update.html', function(err, data){
        res.end(data);
    })
})

3)index.html 파일의 content 클릭 이벤트 스크립트를 수정
        content.addEventListener('click', (e) => {
            //실제로 클릭이 발생한 항목의 id 가 item으로 시작할 때만
            if(e.target.id.startsWith('item')){
                //itemid 만 추출 - item 이라는 4글자를 제외하고
                var itemid = e.target.id.substring(4).trim();
                
                var request = new XMLHttpRequest();
                request.open('GET', '/item/detail?itemid=' + itemid);
                request.send("");
                request.addEventListener('load', () => {
                    //자바스크립트의 데이터로 변환
                    var data = JSON.parse(request.responseText);

                    //출력 영역 초기화
                    updatearea.innerHTML = '';
                    content.innerHTML = '';

                    //출력 내용 만들기
                    var display = "";
                    display += "<div align='center' class='body'>";
                    display += "<h2>상품 상세 화면</h2>";

                    //데이터가 있다면
                    if(data.result == true){
                        var item = data.item;

                        display += "<table>";
                        display += "<tr><td>";
                        display += "<img height='100' width='100' src='/img/";
                        display += item.pictureurl + "'><td>";

                        display += "<td align='center'><table>";
                        
                        display += "<tr height='50'><td width='80'>";
                        display += "상품명</td>";
                        display += "<td width='160'>" + item.itemname;
                        display += "</td></tr>";

                        display += "<tr height='50'><td width='80'>";
                        display += "가격</td>";
                        display += "<td width='160'>" + item.price;
                        display += "원</td></tr>";

                        display += "<tr height='50'><td width='80'>";
                        display += "비고</td>";
                        display += "<td width='160'>" + item.description;
                        display += "</td></tr>";

                        display += "<tr height='50'>";
                        display += "<td colspan='2' align='center' width='240'>";
                        display += "<a href='#' id='mainbtn'>목록보기</a>"
                        display += "</td></tr>";

                        display += "<tr height='50'>";
                        display += "<td colspan='2' align='center' width='240'>";
                        display += "<a href='#' id='deletebtn'>데이터 삭제</a>"
                        display += "</td></tr>";

                        display += "<tr height='50'>";
                        display += "<td colspan='2' align='center' width='240'>";
                        display += "<a href='#' id='updatebtn'>데이터 수정</a>"
                        display += "</td></tr>";
                        

                        display += "</table>"



                    }else{
                        display += "<p>데이터가 존재하지 않습니다.</p>";
                    }
                    content.innerHTML = display;
                    var mainbtn = document.getElementById("mainbtn"); //listbtn누른 효과가 나오게
                    if(mainbtn != undefined){
                        mainbtn.addEventListener('click', (e) => {
                            document.getElementById('listbtn').click()
                        })
                    }

                    var deletebtn = document.getElementById("deletebtn");
                    if(deletebtn != undefined){
                        deletebtn.addEventListener('click', (e) => {
                            var request = new XMLHttpRequest();
                            request.open('POST', '/item/delete', true);

                            //폼이 없고 파일이 없는 상태의 POST 방식 파라미터 만들기
                            var params = "itemid=" + data.item.itemid;
                            request.setRequestHeader('Content-type',
                            'application/x-www-form-urlencoded');
                            request.send(params);

                            request.addEventListener('load', ()=>{
                                var data = JSON.parse(request.responseText);
                                if(data.result){
                                    document.getElementById("listbtn").click();    
                                }else{
                                    alert("삭제 실패");
                                }
                            })

                        })
                    }

                    //수정 버튼을 눌렀을 때
                    var updatebtn = document.getElementById("updatebtn");
                    if(updatebtn != undefined){
                        updatebtn.addEventListener('click', (e) => {
                            var request = new XMLHttpRequest();
                            request.open('GET', '/item/update')
                            request.send('');

                            request.addEventListener('load', ()=>{
                                //수정 화면 출력
                                content.innerHTML = '';
                                updatearea.innerHTML = request.responseText;

                                //수정 화면에 데이터 매핑
                                var item = data.item;

                                document.getElementById('itemid').value=item.itemid;
                                document.getElementById('itemid').readOnly=true

                                document.getElementById('itemname').value=item.itemname;
                                document.getElementById('price').value=item.price;
                                document.getElementById('description').value=item.description;
                                document.getElementById('oldpictureurl').value=item.pictureurl;
                                document.getElementById('picture').src = "/img/" + item.pictureurl;

                                //수정 폼을 찾아옵니다.
                                var updateform = document.getElementById("updateform");
                                updateform.addEventListener('submit', (e) => {
                                    //기본 이벤트 처리 내용을 수행하지 않음
                                    e.preventDefault();
                                    //폼 데이터 가져오기
                                    const formData = new FormData(updateform)

                                    //폼 데이터 전송
                                    var xhr = new XMLHttpRequest();
                                    xhr.open('POST', '/item/update')
                                    xhr.send(formData)

                                    xhr.addEventListener("load", () => {
                                        var data = JSON.parse(xhr.responseText);
                                        if(data.result){
                                            alert("수정 성공");
                                            document.getElementById('listbtn').click();
                                        }else{
                                            alert("수정 실패");
                                        }
                                    })


                                })



                            })

                        })
                    }


                })
            }
        })




4)index.js 파일에 수정 요청 처리를 위한 라우팅 함수 작성

app.post("/item/update", 
    upload.single('pictureurl'), (req, res, next) => {
        //파라미터 읽어오기
        const itemid = req.body.itemid;
        const itemname = req.body.itemname;
        const description = req.body.description;
        const price = req.body.price;
        const oldpictureurl = req.body.oldpictureurl;
        
        var pictureurl;
        if(req.file){
            pictureurl = req.file.filename;
        }else{
            pictureurl = oldpictureurl;
        }

         //삭제하는 날짜(현재 날짜 및 시간)를 생성
        var date = new Date();
        var year = date.getFullYear();
        var month = date.getMonth() + 1;
        month = month >= 10 ? month : '0' + month;
        var day = date.getDate();
        day = day >= 10 ? day : '0' + day
        var hour = date.getHours();
        hour = hour >= 10 ? hour : '0' + hour;
        var minute = date.getMinutes();
        minute = minute >= 10 ? minute : '0' + minute;
        var second = date.getSeconds();
        second = second >= 10 ? second : '0' + second;

        connection.query('update goods set itemname=?,' + 
            'price=?, description=?, pictureurl=?, updatedate=? ' + 
            'where itemid = ?' , 
            [itemname, price, description, pictureurl, 
                year+'-'+month+'-'+day, itemid],
            (err, results, fields) => {
                console.log(err)

                if(results.affectedRows >= 0){
                    //데이터를 수정한 시간을 update.txt에 기록
                    const writeStream = fs.createWriteStream('./update.txt');
                    writeStream.write(year + '-' + month + '-' + day + ' ' + 
                        hour + ':' + minute + ':' + second);
                    writeStream.end();

                    res.json({"result":true})
                }else{
                    res.json({"result":false})
                }
            })
})



19.데이터가 마지막으로 수정된 날짜 및 시간을 제공하는 요청을 index.js 에 생성

app.get('/item/date', (req, res, next) => {
    fs.readFile('./update.txt', (err, data) => {
        res.json({'result':data.toString()});
    })
})



20.이미지 다운로드 구현
1)index.js 파일에 이미지 이름을 매개변수로 받아서 이미지를 다운로드 받도록 해주는 라우팅 함수를 구현

//이미지 다운로드 구현
//최근에 클라이언트에서 서버로 데이터 1개를 보내야하는 경우 파라미터 형태보다는 url 마지막에 작성하는 경우가 많다
app.get('/img/:fileid', (req, res, next) => {
    var fileid = req.params.fileid;

    //다운로드 받을 파일 경로를 설정
    var file ='C:\\jieun\\node\\node_mysql\\public\\img'+ fileid;

    //타입 설정(마인타입으로..)
    mimetype = mime.lookup(fileid)

    res.setHeader('Content-disposition', 'attachment; filename=' + 
    fileid);
    res.setHeader('Content-type', mimetype);
    var filestream = fs.createReadStream(file);
    filestream.pipe(res)
})


2)index.html 파일의 상세보기 처리 부분에서 이미지를 누르면 다운로드 받도록 출력하는 부분을 수정

display += "<a href='/img/" + item.pictureurl + "'>"
display += "<img height='100' width='100' src='/img/";
display += item.pictureurl + "'></a><td>";




**ORM(Object Relational Mapping)
=>객체 지향 패러다임을 RDBMS에 보존하는 기술
=>프로그래밍 언어의 객체 와 데이터베이스의 테이블을 매핑시키는 것
SQL 없이 데이터베이스 작업 가능

1.장점
=>데이터베이스를 변경하고자 할 때 설정 만 변경하면 됩니다.
=>SQL Mapper 보다 성능이 우수

2.단점
=>데이터베이스 구조를 알아야 합니다.
=>learning curve 가 길다고 합니다.

3.실무
=>SI 업계에서는 SQL Mapper 선호
=>솔루션 업계에서는 ORM 선호

4.node 의 mysql ORM을 위한 패키지를 설치
npm install sequelize sequelize-cli mysql2

5.sequelize 초기화 - config, migration, models, seeders 라는 디렉토리가 생성
npx sequelize init

6.models 디렉토리의 index.js 파일을 수정

const Sequelize = require('sequelize');

const env = process.env.NODE_ENV || 'development';
const config = require('../config/config')[env];
const db = {};

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

db.sequelize = sequelize;


module.exports = db;



7.config 디렉토리의 config.json 파일의 접속정보 수정

{
  "development": {
    "username": "root",
    "password": "0000",
    "database": "node3",
    "host": "127.0.0.1",
    "dialect": "mysql"
  },
  "test": {
    "username": "root",
    "password": "0000",
    "database": "node3",
    "host": "127.0.0.1",
    "dialect": "mysql"
  },
  "production": {
    "username": "root",
    "password": "0000",
    "database": "node3",
    "host": "127.0.0.1",
    "dialect": "mysql"
  }
}



8.index.js 파일에 데이터베이스 접속 코드 작성 후 실행하고 콘솔 확인

const {sequelize} = require('./models')
sequelize.sync({force:false})
    .then(()=>{
        console.log('데이터베이스 접속 성공')
    })
    .catch((err)=>{
        console.log(err)
    })



9.데이터베이스에 접속해서 실제 매핑할 테이블을 생성
use node3;

drop table goods;

-- 테이블 생성
CREATE TABLE goods(
id int not null auto_increment,
itemid int,
itemname VARCHAR(100), 
price int,
description VARCHAR(200), 
pictureurl VARCHAR(100),
updatedate varchar(20),
PRIMARY KEY (id)
)engine=InnoDB DEFAULT CHARSET=utf8;

select * from goods;

10.goods 테이블 과 매핑할 모델 파일을 models 디렉토리에 생성하고 작성 - item.js

const Sequelize = require('sequelize')

module.exports = class Item extends Sequelize.Mode{
    static init(sequelize){
        return super.init({
            itemid:{
                type:Sequelize.INTEGER.UNSIGNED,
                allowNull:false,
                unique:true
            },
            itemname:{
                type:Sequelize.STRING(100),
                allowNull:true
            },
            price:{
                type:Sequelize.INTEGER.UNSIGNED,
                allowNull:true
            },
            description:{
                type:Sequelize.STRING(200),
                allowNull:true
            },
            pictureurl:{
                type:Sequelize.STRING(100),
                allowNull:true
            },
            updatedate:{
                type:Sequelize.STRING(20),
                allowNull:true
            }
        },{
            sequelize,
            timestamp:false,
            underscored:false,
            modelName:Item,
            tableName:'goods',
            paranoid:false,
            charset:'utf8',
            collate:'utf8_general_ci'
        })
    }
}















    'Node.js' 카테고리의 다른 글
    • [Node.js] 2022/05/16 : Node_Socket
    • [MongoDB] Day 09
    • [Node.js] Day 07: 데이터 가져와서 출력하기
    • [Node.js + MySQL] Day 06: 노드와 데이터 베이스 연결

    티스토리툴바