카테고리 없음

MVC 구조만들기 / Node.js MySql연결

DevOhwa 2022. 8. 5. 21:43
반응형

220805 금요일

새싹 웹 풀스택과정 갓규리쌤 수업을 바탕으로 작성하였습니다. 

 

참고로... 오늘의 수업은 분명들을땐 다 이해가 갔는데 혼자 글을 쓰고, 해보려니 이해가 안가서 횡설수설하는 포스팅입니다...

mvc에 대한 간단한 설명 포스팅도 곧 할 예정입니다... 

피드백 언제나 환영합니다~!

 

 

 

 

오늘의 수업은 CRUD중에서 Create 와 Read만 진행하였다. 

진행1. MVC 구조만들기

mvc구조

mvc를 위해서 폴더, 파일을 만들어 주었다.

방명록형식의 실습을 진행할것이기 때문에 파일의 이름들은 그와 관련된 visit과 연관지어 만들었다. 

 

최종적으로 이렇게 내가 방명록을 등록하면 아래에 나타나는것을 구현하기위한 학습을 하였다. 

 

 

진행2. 로컬호스트에 방명록 뜨도록 만들기

 

 

첫째로 view 폴더에 있는 index.ejs에 

이렇게 나오도록 기본 설정을 해준다. 

<html>
    <head>
        <title> 방명록 </title>
        <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
        <script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>      
    </head>
    <body>
        <div>
            <form id="form_comment">
              <fieldset>
                <legend>방명록 등록</legend>
                <div><input name="id" type="hidden" placeholder="사용자 이름"></div>
                <div><input name="name" type="text" placeholder="사용자 이름"></div>
                <div><input name="comment" type="text" placeholder="방명록"></div>
                <div id="button-group">
                    <button type="button" onclick="writeComment();">등록</button>
                </div>
              </fieldset>
            </form>
        </div>
        <br>
        <table id="visitr_list" border="1" cellspacing="0" cellpadding="5">
            <thead>
            <tr>
                <th>ID</th>
                <th>작성자</th>
                <th>방명록</th>
                <th>수정</th>
                <th>삭제</th>
            </tr>
            </thead>
            <tbody>
            </tbody>
        </table>       
    </body>
</html>

 

 

 

 

 

 

 

진행3. MySQL로 테이블 만들기

mysql을 이용하여 데이터를 읽는것과, localhost에 저장하는것을 할 예정이므로 workbench에서 테이블을 만들어준다. 데이터베이스는 원래 만들어뒀던것을 이용했다. 

my sql 테이블 만들기

위의 캡쳐에서 id 옆에있는 ' auto_increment ' 는 우리가 사용할 ID칸에 등록하는 수마다 자동으로 숫자를 카운트하는 역할을 해준다. 자동번호 생성기라고 생각하면 된다.

그리고 auto_increment을 이용할 칼럼은 INT형 자료형을 가지고 있어야한다. 중복이 없는것이기 때문에 주로 기본키primary key를 이용한다. 필수는 아니다. 

 

아래와 같은 테이블을 확인 할 수 있다. 

결과값

 

 

 

진행4. Node.js mysql 연결

(당연 init, ejs, express, body-parser 다깔아줘야하는건 잊지말기) 

 

npm i mysql 로 mysql을 설치해준다. 

모델폴더의 Visitor.js에 아래 코드를 선언해준다. model에서만 db에 접근할거기 때문에 mysql을 불러온다.

require를 사용한다. 그리고 딕셔너리 형태로 값을 보내준다. 

 

사전에 우리가 db와 서버를 연결을 시켜놨기 때문에 cnn(connection)으로 던지면 받아준다. 

const mysql = require("mysql");
const cnn = mysql.createConnection({
    host: 'localhost',
    user: 'user',
    password: '****'
    database: 'sesac'
});

 

호스트는 내가 localhost를 사용할것이기 때문이고, database가 'sesac'이기 때문에 적어주고 비밀번호는 내가  mysql을 시작할때 작성하는 비밀번호를 입력해준다. 

그 상태가 서버와 로컬호스트의 연결이 준비가 된것이다. 

 

 

 

 

<Controller안에있는 VisitorController.js파일>에 

const Visitor = require("../model/Visitor");

exports.get_visitors = (req,res) => {
    Visitor.get_visitors();
        res.render("index");
}

모델폴더에 있는 visitor.js에 있는 거 실행하겠다고 선언한다. 

(그런 모델의 visitor.js는 내가 연결한 mysql의 정보들이 들어있다. )

 

<model 폴더에있는 Visitor.js>를 아래 캡쳐와 같이 완성시키고 localhost를 실행시키면

 

>>>앗! 오류가뜬다!<<<

 

 

이유 --> 외부에서 최상위 root로의 비밀번호 접근을 허용하지 않는다. 

즉, 새로운 사용자를 만들고 그 사용자로 접근을 해주어야 한다. 

 

 

진행5. 새로운 사용자 만들기

새로운 사용자를 만들기위해, mysql commandline을 켜준다. 

 

 

등록된 사용자 확인

select host, user, authentication_string from mysql.user;

로 등록된 사용자를 확인해준다. 

 

그리고 

select host, user, plugin from mysql.user; 를 이용하여 외부에서 접근가능한 사용자를 추가해준다. 

ddl, ddm, dcl중에서 dcl을 사용하는것이다. 

 

 

 

 

CREATE USER 'user'@'%' IDENTIFIED BY

 

위의 create user를 사용하여 비밀번호도 설정해준다. 

그리고 다시 확인해보면 user가 추가되었음을 볼 수 있다. 

(옆자리 쥬비가 해줬다ㅎㅎㅎ )

 

GRANT ALL PRIVILEGES ON . TO 'user'@'%' WITH GRANT OPTION;

→ db와 table모두에 접근이 가능하도 grant 가 권한을 부여해 주는것이다. 

 

FLUSH PRIVILEGES;

  권한을 새롭게 불러온다. 

 

ALTER USER 'user'@'%' IDENTIFIED WITH mysql_native_password BY '****';

→ 권한을 관리하는 alter문이다. 

 

 

 

그리고 model의 visitor.js로 돌아가서 내가 위에서 설정한 비밀번호로 바꾸어준다. 

 

 

 

 

 

진행5-1. DB 콘솔 찍어 확인해보기

my sql insert into

workbench 에서 insert into 로 데이터를 입력해준다. 

 

 

 

console.log 확인하기

model - visitor.js에서 콘솔을 찍은것을 확인하면

 

콘솔 결과값

위와같이 내가 쓰는 로컬호스트와 아래에 찍힌 console.log를 확인 할 수 있다. 

 

 

물론 위의 과정에서 만들었던 ejs파일이 다 다르기도하고, 함수를 연결하지 않는등의 실수를 범하는 바람에 선생님의 코드르 고스란히 복사해와 사용했다... 규리쌤...감사합니다...

 

파일을 전부다 드래그 앤 드롭을 했다. 그리고 여기서 작은 꿀팁은 

npm install

을 입력하면 package.json에 있는 dependenciese들이 자동으로 설치된다. 바로 설치해줬다..역시나 쥬비의 꿀팁이었다..ㅎㅎ

 

 

 

진행6. call back 함수 사용

my sql은 비교적 최근에 나온 promise를 적용할 수 없기 때문에 call back함수를 사용해야한다. model에있는 Visitor.js 파일에  db를 가져오기 위해서 콜백을 써준다.

call back

 

참고>> row값은 아래의 캡쳐값이다. database. 

 

 

cb에 내가 검색한 결과인 row를 보내주어야한다. 

따라서 controller의 파일에 함수의 파라미터가 있어야한다. 

 

아래 캡쳐와 같이 넣어준다. 

키값을 넣어준다.

→ 위와같이 넣어준다. (  row가 Visitor.get_visitors ( function( result ) ~)의 result로 가는거임. )

 

 

 

→ data 라는 키값으로 result를 써준다. ejs파일에서 result를 사용하려면 data라는 변수명으로 사용할 수 있다.

 

 

 

진행7. for 문을 사용하여 데이터값을 표현하기

<%
                for ( let i = 0; i < data.length; i++ ){                   
            %> 
                <tr>
                    <td><%=data[i].id%></td>    
                    <td><%=data[i].name%></th>
                    <td><%=data[i].comment%></td>
                    <td></td>
                    <td></td>
                </tr>
            <%
                }
            %>

ejs 파일에 data값을 표현해준다. data는 아까 위에서 본 result 값이다. 

위의 for 문을 이용해서 내가 입력한 정보들이 각 아이디와 네임 코멘트에 나타날 수있도록 해준다. 

 

위의 코드를 사용하면 내가 sql에서 작성했던 데이터값이 아래와 같이 로컬호스트에 나타남을 볼 수 있다.

내가 입력한 데이터값

참고로 tr은 가로줄(행) / th(헤더) & td 는 세로줄(열)이다.

tr과 td 태그로 표현해주면 내가 만든 방명록의 양식대로 내 데이터들을 확인 할 수 있다.

 

 

 

 

 

 

 

 

진행8. 동적 폼전송(내 로컬호스트에 적어서 데이터 바로 추가시키기)

 

우선 view폴더의 ejs파일에 axios와 제이쿼리를 가져온다. 

<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
<script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>

<button type="button" onclick="writeComment();">등록</button>

→ 방명록등록에 사용되는 '등록'버튼을 button타입과 wirteComment 온클릭을 설정해준다. 

 

 

 

그리고 아래 인풋태그에 name속성을 하나하나 다 설정해준다. 

<div>
            <form id="form_comment">
              <fieldset>
                <legend>방명록 등록</legend>
                <div><input name="id" type="hidden" placeholder="사용자 이름"></div>
                <div><input name="name" type="text" placeholder="사용자 이름"></div>
                <div><input name="comment" type="text" placeholder="방명록"></div>
                <div id="button-group">
                    <button type="button" onclick="writeComment();">등록</button>
                </div>
              </fieldset>
            </form>
        </div>

 

 

 

그리고 아래의 코드를 head script 에 추가해준다. 

 <script>
            function writeComment(){
            
            }
 </script>

→ 사용자가 이름과 방명록을 적으면 back으로 넘기고 back이 db에 값을 넣고 처리를 해줄것이다. 

 

 

 

            function writeComment(){
                var form = document.getElementById("form_comment");
                //for take the comment
                axios({
                    method: 'post',
                    url: 'http://localhost:8000/visitor/write',
                    //여기로 보내겠다.
                    data: {
                        name: form.name.value,
                        comment: form.comment.value
                    }
                })
                .then((rep) => { 
                	console.log(rep) 
                });

참고로 위의 data 에는 id가없다.

우리가 안적어줘도 id가 우리가 등록하는대로 숫자가 카운팅되어 올라 갈 수 있는것은 mysql에서 auto_increment를 설정했기 때문이다. 그래서 네임과 코멘트만 해주면 된다.  

 

→ 여기서 보내는 데이터값은 보시다시피 name과 comment값이다. 

보내기전에 router에서 경로를 만들어주어야 한다. 

 

index.js
router의 index.js / visitor.post_comment를 ctrl커서로 눌러보면 controller로 연결되어있음을 확인 할 수 있다. .

→ 위의 캡쳐와 같이 각각의 인덱스 파일에 설정을 해주어야한다. 

router에서 controller안에 어떤함수를 실행할거라고 말한거라서 router에 만들어주어야한다. 만들지 않는다면 당연하겠지만 실행이 되지 않는다. 

 

 

아래의 캡쳐는 controller의 캡쳐이다. route와 controller가 다음과 같이 연결되어있음을 확인할 수 있다.

(개인적으로 이렇게 연결짓는 부분을 잘 못지어서 많은 오류가 났다.)

 

→ 위의 controller에서 Model의 Visitor 에게 3개의 값을 보냈음을 알 수 있다. (name, comment, cb)

 

 

 

 

모델의 visitor에서 받아온 값을 어떻게 나타낼지 설정해주면 된다.

 

var sql = "INSERT INTO visitor(name, comment) VALUES('" + name + "', '" + comment + "')";

//위의 코드는 아래처럼 나눠서 생각해주면 그나마 편하다.
" INSERT INTO visitor(name, comment) VALUES(' "
+ name + 
" ', ' " 
+ comment + 
" ') ";

위와 같은예시로는 아래 캡쳐인데, 아래처럼 문자가 합쳐진다고 생각하면 편하다. 나는..편했다. 

 

 

 

그리고 rows는 데이터이다. 아래의 캡쳐를 참고하면 된다. 

그중 우리는 insertId 값만 필요하다. 위에서 언급했듯이 id는 mysql에서 우리가 입력한만큼 자동으로 카운팅된다. 

model의 cb( rows.insertID); 는 controller에 있는 함수로 보내준다. 

 

 

result

→ 저기 result에 n번째 insertId가 들어온다.

(계속 언급하지만, 내가 mysql에서 해줬던 설정auto_increment때문에 내가 넣는 데이터값이 알아서 카운터 되어서 들어옴)

 

그리고 res.send에서 id:result로 선언해준다. 그리고 저 친구들은 view폴더의 ejs파일로 넘어간다. 

 

ejs
view 폴더안에 있는 ejs 파일

→ controller에서 넘어온 result는 rep.data로 들어간다. 

 

→ 그리고 html을 이용하여 데이터를 내 로컬호스트에서 가시적으로 볼 수 잇도록 사용해준다. 

let html을 만들고 append를 이용한다. 

 

 

 

다설정해주고나면 로컬호스트에서 내가 입력한 이름과 방명록이 등록버튼에 의해서 3번에 나타남을 확인 할 수있다. 

드디어 끝~!

 

 

오늘의 문제점

- 수요일에 배웠던 mvc의 개념이 완벽하지 못했다. 때문에 오늘 수업의 이해가 더뎠음.

- 더 전에 배웠던 cb, promise, axios개념이 확립이 완벽하지 못해서 따라가는데 어려움이 있었다. 

- controller, model, route, view...에 각각의 파일들의 구조를 연결짓지 못해서 생기는 오류가 많았다.

- 오타가 많았다.

 

 

문제점이 해결되었는가

- 오늘 실습을 진행하면서 mvc가 무엇인지에 대해서 조금 더 알게 되었다. 

- cb 와 promise, axios에 대해서는 전에 학습받았던것을 위주로 복습을 진행할 예정이다. cb는 오늘의 실습을 통해서 어느 정도 기억이 떠올랐고, 오늘 진행한 실습건에 대해서 설명이 가능하지만  axios와 promise는 복습이 필요해 보인다.

- 서로다른 폴더들의 유기적인 관계에 대해 이해가 가능한 실습이었다. 아직도 헷갈리지만 다시한번 실습을 따라해봄으로써 이해를 스스로 해볼 예정이다. 

- 오타는... 언제나 조심하려고 노력중이다

 

 

 

 

*피드백 환영*