생각기록
2022-12-01 MVC 패턴, 방명록 본문
MVC
model view controller
소프트웨어 설계와 관련된 디자인 패턴
> 상황에 따라 자주 쓰이는 설계 방법을 정리한 코딩 방법론! ( 문법 X )
- model은 데이터베이스 연동
- view는 클라이언트
- controller는 모델 뷰사이 중간다리
MVC를 이용한 웹 프레임워크
- PHP
- Django
- Express
- Angular
MVC 장단점
장점
- 패턴들을 구분해 개발한다 (어디에 사용하는지..)
- 유지보수 용이 ( 나눠놓고 분리해서 작업하기 때문에 )
- 유연성이 높다
- 확장성이 높다
- 협업에 용이하다 ( 한 파일을 건드리면 깃이나 이런데서 충돌이 발생하기 때문에 )
단점
- 완벽한 의존성 분리가 어렵다 (기능별 분리가 어렵다)
- 설계 단계가 복잡하다
- 설계 시간이 오래 걸린다
- 클래스가 많아진다. (파일안에 선언된 클래스가 많아짐)
그래도 장점때문에 쓸것이다
mvc의 흐름

클라이언트 > 브라우저
라우터: url 주소 정의
컨트롤러 : 클라이언트가 요청하는 것을 여기에 분리해 둔다.
예) 메인페이지 : 로그인 여부에 따라 화면을 다르게 보여주고 싶은 요청 같은 작업을 컨트롤러로 하고 브라우저로 랜더
컨트롤러는 그 사이에 또 모델이랑 소통하는데 모델은 데이터베이스와 소통한다.
뷰 = 브라우저랑 연결 되어 있다
컨트롤러 - 어떤 뷰를 랜더링 할 것인지 결정한다.
model
데이터를 처리하는 부분
view
ui관련된 것을 처리하는 부분 ( 사용자에게 보여지는 부분 )
프론트엔드는 뷰안에서 작업하게 됨
controller
view와 model을 연결해주는 부분
2022-12-01 오늘 폴더 구조가 기존과 다를 것이다.
폴더구조를 ( 이름은 상관없음 > 상대경로로 불러올거기 때문! ) 만들어주기!
- controller
- model
- routes
- views
모듈 설치
npm init --yes
npm install express
npm install ejs
npm install -g nodemon
npm install multer
npm install mysql
최상위 index.js파일 생성
view에는 로그인페이지를 만들거여서 login.ejs 파일
user에 관한 모델이다 > model/User.js
routes에 index.js
controller > CUser.js파일



require은 모듈을 불러오겠다는 뜻
./routes는 상대경로로 폴더까지만 썼을때 자동으로 그 안의 index파일에 한해서는 연결해 줌
routes라는 폴더 안 그 안에 index.js가 있다면, 알아서 index.js까지 연결해 줌!
index가 아닌 한에서는 파일까지 지정해줘야 한다.
app.use ( '/' , router );
localhost:8000/ ~~~~
8000 포함, ~~~ 어떤 것들이 와도 router라는 변수에 넣겟다 라는 의미

없는 라우터를 치면 error => 404 에러라고 합니다.
클라이언트는 당황 할 수 있다
이것을 당황하지 않게 도와줄
위에없는 라우터에 대한 404에러 핸들링은

이런식으로 도와줍시다.

라우터 관련 정의는
routes 폴더 파일

routes 폴더의 index.js파일
라우터가 보여줄 행위를 컨트롤러 폴더에서 한다고 require 하고 있다.
controller/Cmain 파일을 불러서 쓴다.
Cmain.js 파일 routes 폴더 파일이 끌어다 쓴다고 했다.
여기서 controller는 view와 model을 연결

여기서 views의 index.ejs파일을 연결이 됬는지 확인
view는 클라이언트가 보게 될 화면

model > Test.js 파일
모델은 데이터베이스와 소통하는 곳
hello라는 객체에 'hello'라는 문자열을 반환하는 함수를 담고 exports로 처리 했다.

이것을
controller> Cmain.js 파일에서
const Test = require ('../model/Test');
require test.js파일을 불러왔고
이 기능을
let hi = Test.hello();
hi라는 변수에 값을 받는데
> Test라는 객체에 .hello라는 함수 (Test.js파일에서 정의한)를 호출 했다.
이 함수에는 'hello'라는 문자열을 담고 있다.

제대로 되는지 확인해보자
res.send(hi);
hi라는 객체를 보여준다.

실습 1



1. 최상위 js 파일에서 라우터를 불러오는 객체를 설정
//라우터를 불러오는 부분
const router = require('./routes/app');
app.use('/', router);
require > ./routes/app.js 파일에 라우터 정보들을 불러온 객체 router
즉 ./routes/app.js에서 라우터들을 정의해줘야 한다.
app.use('/', router);
app.use 미들웨어이면서
기본 라우터('/') 포함해서 모든 라우터를 router객체를 통해 불러오겠다 라는 뜻이다.
2. ./routes/app.js 파일
var express = require('express');
var controller = require('../controller/Cmain');
//라우터 정의 재료 외우기
const router = express.Router();
//라우터에 대한 모든 것을 여기다 저장(정의)
router.get("/login", controller.login);
router.post("/login", controller.loginPost);
router.post("/login2", controller.loginPost2);
> controller . 함수 얘를 > /라우터 에 기능을 넣겠다 라는 뜻!!!
그 기능을 controller 역할 파일가서 확인해야 한다.
module.exports = router;
controller 파일에 해당 함수들이 있어야 한다.


최상위 js파일에서 필요로 하는 라우터에 대한 정의
var controller = require('../controller/Cmain');
여기서 컨트롤러 객체에 ../controller/Cmain.js 파일에서 컨트롤 하겠다.
즉 라우터 컨트롤은 Cmain이란 파일에서 하겠다는 의미
3.../controller/Cmain.js 파일

해답 1
exports.main = (req, res) => { res.render('login'); }
exports.login = (req, res) => { if ( req.body.id == "1" && req.body.pw == "1234" ){ res.send({msg: "<p style='color:blue'>post 로그인 성공</p>"}); } else { res.send({msg:"<p style='color:red;'>post 로그인 실패 ( 아이디 또는 비밀번호가 틀렸습니다.)"}); } }
해답1로 하면 기능적으로는 끝나는데, 데이터베이스와 소통할 model에서 기능을 넣고 분리해보고 싶다.
해답 2 model 응용
const Test = require('../model/Test');
//해당 파일데이터를 객체 삽입
//라우터에 넣었던 함수들을 정의해준다.
exports.main = (req, res) => { res.render('login'); }
exports.login = (req, res) => { if ( req.body.id == "1" && req.body.pw == "1234" ) //아이디 1, 비번 1234 면 true
{ res.send({msg: "<p style='color:blue'>post 로그인 성공</p>"}); }
else { res.send({msg:"<p style='color:red;'>post 로그인 실패 ( 아이디 또는 비밀번호가 틀렸습니다.)"}); } }
해답 2
4. model 데이터베이스에서 정보를 가져오는 파일 연결
const Test = require('../model/Test');
그에대한 정보들은 ../model/Test.js 파일에서 설정하겠다.
test.js


login 이라는 함수는
id : "1"과 pw : '1234' 라는 객체 값을 반환한다.
아이디 비번 키값으로 데이터 넣고!
이 데이터를 참조하고 있는 컨트롤러 파일로 다시 돌아가서
저 데이터를 요리할 수 있도록 해야 한다.
5. 컨트롤러에서 라우터에 보낼 데이터를 처리 할 기능 만들기
클라이언트의 요청값 req.body.id = 객체.key 값으로 한다.
let info 라는 객체에 model 파일의 login()함수를 넣는다. // id : "1"과 pw : '1234' 라는 값을 갖고 있다.
info.id와 클라이언트가 입력한 값이 동일하면 true

6. (controller에서 클라이언트가 보낸 데이터와 데이터베이스(model)이 소통해서 서버에 전달하고)
서버는 view 파일에 응답한다.
ejs 파일에서
서버의 응답값을 받는 then
}).then((response) => {
let result = response.data; // result라는 객체 값의 key로 msg 호출
document.getElementById("result").innerHTML = result.msg;
});
}


선생님의 해답
폴더구조를 ( 이름은 상관없음 > 상대경로로 불러올거기 때문! )
controller
model
routes
views
최상위 index.js파일 생성
view에는 로그인페이지를 만들거여서 login.ejs 파일
user에 관한 모델이다 > model/User.js
routes에 index.js
controller > CUser.js파일
다른건 다 똑같지만
최상위 js
const router = 어디서?
require('./routes') //index.js파일
app.use('/', router);
,/routes/index
const express = require('express');
const router = express.Router(); 익스프래스를 통해 라우터를 생성
const controller = require('../controller/CUser');
//http에 맞는 것을 가져오면된다 1. 로그인 페이지 렌더 get요청 필요
router.get('/login', controller.login); //login이라는 얘는 컨트롤 파일에 있는 함수일것이다
module.exports = router; //기능 내보내기
CUser 파일에 가서 login함수 만들어줘야 한다.
exports.login = func
서버에 보낼 요청을 참고해서
axios, post
,/routes/index
에서
router.post('/login', co~.loginPost);
loginPost 함수를 만들러 가야한다
다시
CUser 파일에
exports.loginPost = (req,res) => {
"1", "1234"
if ( req.body.id == "1" && req.body.pw = '1234') 둘다 만족한다면
res.send('로그인 성공');
else res.send('로그인 실패');
모델은 mysql에 연결되어있고, 데이터베이스에 저장이 되어있을 것이다.
즉 위의 "1", "1234"는 model관련 파일에 넣어줘야 한다.
model/User.js
exports.user = () =>{
return {id: "1", pw "1234"};
}
이것을 다시 컨트롤러 파일 CUser.js파일에서 불러와야한다
const User = require('../model/User');
exports.loginpist = (req,res) => {
let info = User.user();
if ( req.body.id == info.id && req.body.pw = info.pw)
res.send('로그인 성공');
else res.send('로그인 실패');
}
제대로 뜨면 성공!
model/User.js
model/Test.js

routes 폴더 js
/login2 라우터에 controller객체의 login2라는 함수가 있다.


mvc 구조 만들기
1. 새로 폴더구조를 만들어준다.

2. 각각 기능을 할 파일들을 구조화 시킴
views의
visitor.ejs 파일

<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js" integrity="sha384-NAifrtbJwcoqjYqhfos40lsRt+O6K5TClF4FjW02ZswKdcD2H3gZN3KA1I3ZxYEM" crossorigin="anonymous"></script>
<script src="https://code.jquery.com/jquery-3.6.1.min.js" integrity="sha256-o88AwQnZB+VDvE9tvIXrMQaPlFFSUTR+nldQm1LuPXQ=" crossorigin="anonymous"></script>
</head>
<body>
<form id="form_register">
<fieldset style="display: inline-block;">
<legend>방명록 등록</legend>
이름<input type="text" name="name" placeholder="사용자 이름"><br>
방명록<input type="text" name="comment" placeholder="방명록"><br>
<div class="register-btn">
<button type="button" onclick="register();">등록</button>
</div>
</fieldset>
</form>
<table border="1" cellspacing="0" cellpadding="10" style="margin-top: 30px;">
<tr>
<td>ID</td>
<td>작성자</td>
<td>방명록</td>
<td>수정</td>
<td>삭제</td>
</tr>
</table>
최상위 js 파일

라우터 정의 파일

컨트롤러 파일

3. 서버 연결 확인 후
model 데이터 베이스 연결
모델 폴더 js파일

비밀번호는 사진에 임의로 해둔것이지만!
실제 mysql 데이터베이스에 해당하는 비밀번호를 적어줘야 한다.
4. 워크벤치로 간다
가서 visitor 테이블 생성
create table visitor(
id int not null primary key auto_increment,
name varchar(10) not null,
comment mediumtext
);
auto_increment라는 컬럼 속성은 > 자동으로 1씩 증가 시키겟다
아이디는 not null이지만 아이디는 값을 넣지 않아도 1이라고 생성될 것이다.
값을 추가한다
insert 테이블이름 ( 필드 ) 에 values ( 값 ) 넣는다.
insert into visitor(ID, name, comment ) values('1', '홍길동', '내가 왔다');

워크 벤치작업까지 마무리 됬으면
우리가 해야 할
작업 목록을 살펴 본다.


node.js mysql 연결
view 뿐만 아니라, db에 영향이 갈 수 있도록 할 것임


하지만 자바스크립트는... 비동기다
mysql은 쿼리날리는것이 너무 오래걸린다 (cnn.query) 그래서 콜벡함수를 넘기면서라도
실행을 시켜야 한다.
그래서 이 구조를 사용해야 한다는 것을 외워서 쓰자!
모르면 외우고 익숙해진다음 해석을 하자
그래서 밑에처럼 해야한다.

visitor.ejs 랜더하며 model/visitor의 데이터를 보기위해 ? 데이터 넘긴다?
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js" integrity="sha384-NAifrtbJwcoqjYqhfos40lsRt+O6K5TClF4FjW02ZswKdcD2H3gZN3KA1I3ZxYEM" crossorigin="anonymous"></script>
<script src="https://code.jquery.com/jquery-3.6.1.min.js" integrity="sha256-o88AwQnZB+VDvE9tvIXrMQaPlFFSUTR+nldQm1LuPXQ=" crossorigin="anonymous"></script>
넣어주고
자이제
등록버튼을 ㄴ르면 실해오디도록
ejs파일로 가자

아이디는 서버에서 받아서 사용할 거고
작성자 방명록은 form.name.value를 사용할 예정이다.

ㅇㄴㅁㅇ 내 해석.. 검사




'SeSAC 풀스택 > MYSQL' 카테고리의 다른 글
| 서버 연결 ( 외부 접속 가능 ) / 로컬서버와 서버의서버가 다르다는 사실.. (0) | 2022.12.27 |
|---|---|
| 2022-12-01 MYSQL nodejs와 연결 (0) | 2022.11.30 |
| 2022_11_30_NULL MY SQL 쿼리 조건문 블로그 참고 (0) | 2022.11.30 |
| 2022-11-29 데이터베이스, mySQL 환경설정 기본개념 (0) | 2022.11.29 |