Node.js + MongoDB 공부 - part 2

YuJangHoon·2022년 2월 3일

Web-Development

목록 보기
4/6
post-thumbnail

Node.js + MongoDB를 공부해보자! 위대하신 코딩애플(codingapple.com)님과 함께:)

MongoDB

MongoDB 연결 방법

  1. 터미널에서 npm install mongodb 입력해서 라이브러리 설치
  2. js파일 상단에 코드입력
const MongoClient = require('mongodb').MongoClient;
  1. 하단에 코드 입력
<script>
var db; 
MongoClient.connect('MongoDB에서 가져온 URL', 
function(err, client) {
    if (err) {return console.log(err)}

    // db라는 변수에 TodoApp이라는 데이터베이스를 연결.
    db = client.db('TodoApp')
	// 연결 후에 8080으로 lisetn.
    app.listen(8080, function() {
        console.log('listening on 8080')
    });
})
</script>

collection에 데이터추가 - insertOne

<script>
db.collection('post').insertOne({이름 : "ryu.jh"}, function(err,result) {
	if (err) {return console.log(err)}
    ...
	저장되면 실행될 코드
}) 
</script>

아까 지정했던 데이터베이스가 연결된 db의 collection 중에서 post라는 것을 고르고, 거기에 {이름 : "ryu.jh"}를 insertOne한다는 뜻이다.

되도록 에러가 일어났을 때 로그를 확인할 수 있도록 처리해두는 것이 좋다

또, db.collection('콜렉션 선택').사용할함수() 이런 패턴이 자주 나온다!

EJS 사용법 - .find() / .toArray()

  • 가져온 DB를 사용하려면, EJS 같은 템플릿 엔진을 사용해서 쉽게 서버 데이터를 넣을 수 있게 해야한다.
  1. npm install ejs
  2. app.set('view engine', 'ejs'); 를 js파일에 적는다.
  3. 똑같이 html파일을 만들되, views라는 이름의 폴더에 .ejs 확장자명을 사용해 파일을 만든다.

이제 HTML에서 사용할 수 있는 대표적인 문법 2가지는
1. <%= 서버에서 가져온 데이터 %>
2. <% 자바스크립트 문법 사용 (if, for 등등) %>

끝이다!

데이터는 어떻게 가져오냐구요?

<script>
app.get('/list', function(req,res) {
    db.collection('post').find().toArray(function(err, result){
        console.log('post의 모든 데이터를 가져온 결과 입니다 : ', result);
        res.render('list.ejs' , { posts : result})
    });
}) 
</script>
  • 데이터베이스에 저장된 post라는 collection 안에있는 모든 데이터를 가져온다 .find().toArray() >> 마치 json 파일처럼 나타남
  • 찾은 데이터를 posts라는 이름으로 list.ejs 파일에 넣어서 응답에 render해주세요 라는 뜼이다. 참 쉽쥬?

_id를 달아야하는 이유? - updateOne

나중에 다루기(삭제, 수정 등) 쉬우니까!

다른 SQL 친구들처럼 Auto-Increment 기능이 있으면 좋으겠지만... mongodb에는 그런게 없다하니 직접 만들어야한다.

그러면 게시물을 만들때 (/add라는 api로 post요청을 할때), 자동증가하는 id가 달리게 만들어보자!

<script>
app.post('/add', function(req, res) {
    //db의 collection중에서 counter선택. 게시물갯수의 값을 불러와서 "총게시물갯수"라는 변수에 저장
    db.collection('counter').findOne({name : "게시물갯수"}, function(err, result){
        if (err) {return console.log(err)}

        console.log('터미널에 표시 - 현재 총 게시물 갯수 :', result.totalPost);
        var 총게시물갯수 = result.totalPost;
        //db의 collection중에서 post 선택. id가 총게시물갯수+1인 데이터를 insertOne.
        db.collection('post').insertOne({_id : 총게시물갯수 +1, 제목 : req.body.title, 날짜 : req.body.date}, function(err, result){
            console.log('터미널에 표시 - DB 저장완료');
            res.send('페이지에 표시 - DB 저장완료');
            
            //counter선택. name이 "게시물갯수"인 데이터의 totalPost를 1만큼 increment해서 updateOne.
            db.collection('counter').updateOne({name : "게시물갯수"},{ $inc :{totalPost : 1}},function(err, result){
                if(err) {return console.log(err)}
            })
        });
    })
})
</script>

Ajax 이용하기 - deleteOne

정신건강을 위해 jQuery와 함께 이용하는 Ajax이다!

EJS 파일에는 AJAX로 이렇게 기능을 구현하고

<script>
// btn-delete라는 class를 가진 요소를 클릭하면
$('.btn-delete').click(function(e) {
    $.ajax({
    	//method는 DELETE, api는 /delete, 전달할 데이터는 글번호
        method : 'DELETE',
        url : '/delete',
        // 현재 클릭된 (e.target)의 data-id
        data : { _id : e.target.dataset.id}
        }).done( (result)=>{
        	// $(this)는 지금 누른거
            // 지금누른거의 부모요소 중에서 li를 찾아 fadeOut()
            $(this).parent('li').fadeOut();
        }).fail(function(XMLHttpRequest(몰라도됨), 에러코드, 에러메세지){
			// 실패했을때 실행될 코드
        });
})
</script>

JS 서버 파일에는 이렇게 진행하면된다!

<script>
  // /delete라는 api 요청이 들어오면
  app.delete('/delete', function(req, res) {
  	// post라는 콜렉션에서 _id가 request의 body의 _id와 동일한 것을 하나 찾아서 삭제한다.
    db.collection('post').deleteOne({_id : parseInt(req.body._id)}, function(err, result) {
        if (err) {
            // 응답코드 400, 실패
            res.status(400);
            return console.log(err)
        }
        console.log('삭제완료');
        // 응답코드 200, 일반적으로 성공
        res.status(200).send({ message : '성공했습니다' });
    })
})
</script>

특이한 점은, deleteOne안에 있는 쿼리문의 parseInt()인데, 데이터가 넘어오면서 자동적으로 String 형태가 되어있기 때문에, typeCasting을 통해서 데이터베이스에 있는 Int타입과 동일하게 해주어야된다.

또한 고객 요청에 응답하는 방법은 이런 것들이 있다! (json빼고 다 썼던 거)

<script>
app.get('/api', function(req, res){
  res.send('<p>some html</p>') // 간단한 문자 or html
  res.status(404).send('Sorry, we cannot find that!') // 응답코드
  res.sendFile('/uploads/logo.png') // staticFile 전송
  res.render('list.ejs', { ejs에 보낼 데이터 }) // EJS 등의 템플릿 페이지
  res.json(제이슨데이터) // json 데이터 전송
});
</script>

URL parameter

<script>
//url의 파라미터. /detail/아무거나 라면 실행된다.
app.get('/detail/:id', function (req, res) {
    // _id가 request의 parameter들 중 id와 같은 데이터를 찾아와서 그 결과를 detail페이지에 render
    // 다만 아까처럼 type이 string이 되었기에, parseInt를 통해서 바꿔 찾아줘야한다.
    db.collection('post').findOne({ _id: parseInt(req.params.id) }, function(err, result) {
        if (err) { return console.log('findOne Error', err) }
        res.render('detail.ejs', {foundData : result})
    })
});
</script>
profile
HYU DataScience, ML Engineer - 산업기능요원(4급)

0개의 댓글