https://becomefullstackdev.tistory.com/47
1. node. js 설치 https://nodejs.org/ko/ Node.js Node.js® is a JavaScript runtime built on Chrome's V8 JavaScript engine. nodejs.org 해당 홈페이지에 들어가서 자신의 운영체제에 맞는 버젼을 다운받아서..
becomefullstackdev.tistory.com
- powershell 권한 변경하기
ExecutionPolicy (현재정책확인) -> Restricted 인지 확인
set-ExecutionPolicy Unrestricted (정책을 제안 해제) -> Unrestricted 로 설정
- express에서 데이터를 입력받아서 웹상에 출력하는 과정
애플리케이션 레벨과 라우터 레벨은 실행단계의 차이지 기능적으로는 다른 점이 없다. 애플리케이션 분기 + 라우터 분기로 더 세세허게 요청 URL(파일 경로로 생각하자)을 분리하여 제어가 가능하다는 점이다.
var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');
app.use('/', indexRouter);
app.use('/users', usersRouter);
애플리케이션 단계에서 '/'와 '/users'로 URL을 분리하여 처리를 하도록 한것이다.
var express = require('express');
var router = express.Router();
/* GET home page. */
router.get('/', function(req, res, next) {
res.render('index', { title: '식도락 여행' });
});
module.exports = router;
위의 코드는 라우터 단계의 미들웨어이다. app.use()처럼 router.use()도 쓸 수 있고 app,method()처럼 router.method()도 사용 가능하다. 다른점은 use()는 모든 METHOD에서 동작한다는 것이고 METHOD()는 지정된 요청 (GET, POST, PUT, DELETE 등)에서만 동작을 한다는 것이다.
<!DOCTYPE html>
<html>
<head>
<title><%= title %></title>
<link rel='stylesheet' href='/stylesheets/style.css' />
</head>
<body>
<h1><%= title %></h1>
<p>Welcome to <%= title %></p>
</body>
</html>
router를 통해서 받은 index.js의 title값을 <%= title %>의 형태로 받아서 웹상에 출력할 수 있다. 필자는 '식도락 여행' 페이지 명을 설정했으니 아래와 같이 나올 수 있다.
- 익스프레스의 index.ejs를 수정하여 웹페이지를 꾸며보자.
※ EJS는 Embedded JavaScript templating의 약어로서, 자바스크립트로 HTML 마크업을 생성할 수 있는 간단한 템플릿 언어이다. (JSP와 동일한 역할을 한다.)
- 초기본
ex02>app.js
var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');
app.use('/', indexRouter);
app.use('/users', usersRouter);
app.use('/photos', require('./routes/photos')); //*****
app.use('/notice', require('./routes/notice')); //*****
[new] ex02>routes>photos.js
var express = require('express');
var router = express.Router();
/* GET users listing. */
router.get('/', function(req, res, next) {
res.send([
{id: 1, image:'/images/img01.jpg', title:'명태냉면1인분', price: 8700},
{id: 2, image:'/images/img02.jpg', title:'오징어볶음1인분', price: 8900},
{id: 3, image:'/images/img03.jpg', title:'채끝 찹스테이크', price: 9100},
{id: 4, image:'/images/img04.jpg', title:'플랫브레드루꼴라피자1인분', price: 8900},
{id: 5, image:'/images/img05.jpg', title:'불락전골1인분', price: 10900},
{id: 6, image:'/images/img06.jpg', title:'닭볶음탕1인분', price: 7800},
{id: 7, image:'/images/img07.jpg', title:'자장밥1인분', price: 2800},
{id: 8, image:'/images/img08.jpg', title:'황태양념구이1인분', price: 7800},
]);
});
module.exports = router;
[new] ex02>routes>notice.js
var express = require('express');
var router = express.Router();
/* GET users listing. */
router.get('/', function(req, res, next) {
res.send([
{id: 1, title:'자기의 일은'},
{id: 2, title:'스스로 하자'},
{id: 3, title:'알아서 척척'},
{id: 4, title:'스스로 어른'},
{id: 5, title:'와아아 아아'},
]);
});
module.exports = router;
ex02>routes>views>index.ejs
<!DOCTYPE html>
<html>
<head>
<title><%= title %></title>
<link rel='stylesheet' href='/stylesheets/style.css' />
<script src="http://code.jquery.com/jquery-3.1.1.min.js"></script>
</head>
<body>
<div id="container">
<div id="header">
<img src="http://placehold.it/140/140" width="140" height="140" id="image"/> <!--인터벌로 이미지 넣을곳-->
<img src="/images/download.jpg" width="750" />
</div>
<div id="content">
<h3>[라이언 MD의 추천상품]</h3>
<div id="photos"></div>
<h3>[SNS 고객후기]</h3>
<div id="slider">
<!-- 실제 보여지는 부분-->
<div id="foods"></div> <!-- 이미지 집합-->
</div>
<div id="pagination">
<button id="prev" disabled><</button> <!-- < <-->
<button id="next">></button> <!-- > >-->
</div>
<h3>[공지사항]</h3>
<table id="tbl">
</table>
</div>
<div id="footer">
<h3>Copyright ICIA 이주성</h3>
</div>
</div>
</body>
<script>
let page = 0;
//다음 버튼 클릭
$('#next').on('click', function () {
page++;
change();
});
//이전 버튼 클릭
$('#prev').on('click', function () {
page--;
change();
});
//이미지이동
function change() {
$('#foods').animate({
left: -page * 110
}, 1000);
if (page == 0) $('#prev').attr('disabled', true);
else $('#prev').attr('disabled', false);
if (page == 3) $('#next').attr('disabled', true);
else $('#next').attr('disabled', false);
};
let images =[];
// 슬라이드로 이미지 출력
$.ajax({
type: 'get',
url: '/photos',
dataType: 'json',
success: function (data) {
let str = '';
$(data).each(function () {
let image = this.image;
images.push(image);
let id = this.id;
str += '<div class="item">';
str += `<img src="${image}" width="100"/>`;
str += `<div>${id}</div>`;
str += '</div>';
});
$('#foods').html(str);
}
});
let index=0;
$('#image').attr('src', images[index]);
setInterval(() => {
$('#image').attr('src',images[index % 5]);
index++;
}, 1500);
// 8(4*2)개의 상품이미지 출력
$.ajax({
type: 'get',
url: '/photos',
datatype: 'json',
success: function (data) {
let str = '';
$(data).each(function () {
let id = this.id;
let image = this.image;
let title = this.title;
let price = this.price
if (id <= 8) {
str += '<div class="box">';
str += `<img src="${image}"/>`;
str += `<div class="title">${id} : ${title}</div>`
str += `<div class="price">${price}원</div>`
str += '</div>';
};
$('#photos').html(str);
})
}
})
// 공지사항 출력하기
$.ajax({
type: 'get',
url: '/notice',
dataType: 'json',
success:function(data){
let str ='';
$(data).each(function(){
let id = this.id;
let title = this.title;
str += '<tr>'
str += `<td>${id} : ${title}</td>`
str += '</tr>'
});
$('#tbl').html(str);
}
})
</script>
</html>
[new] ex02>public>stylesheets>style.css
#container {
width: 940px;
margin: 10px auto;
padding: 20px;
border: 1px solid orange;
}
#header {
padding: 20px;
margin-bottom: 20px;
border: 1px solid orange;
}
#content {
width: 900px;
padding: 20px;
margin-bottom: 20px;
float: left;
border: 1px solid orange;
}
#content {
text-align: center;
}
#sidebar {
width: 260px;
padding: 20px;
margin-bottom: 20px;
float: right;
border: 1px solid orange;
}
#footer {
clear: both;
padding: 20px;
border: 1px solid orange;
}
#footer h3 {
text-align: center;
}
#photos{
overflow: hidden;
}
.box{
width: 210px;
float: left;
border: 1px solid yellow;
margin: 5px;
box-shadow: 10px 10px 10px yellowgreen;
}
.box .title{
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
margin: 5px;
}
#slider{
margin: 0px auto;
position: relative;
overflow: hidden;
width: 550px;
height: 150px;
}
#foods{
position: absolute;
overflow: hidden;
width: 880px;
/* 8개가 들어가야해서 880px */
}
.item{
width: 100px;
margin-left: 10px;
float: left;
}
#pagination{
width: 500px;
margin: 0px auto;
text-align: center;
}
#tbl{
width: 800px;
margin: 0px auto;
}
td{
border-bottom: 1px solid orange;
padding-bottom: 10px;
}
- MySQL - DB에 정보를 입력하고 그 정보를 넣어보자
※ db를 사용하기전에 'use (해당db명);' 을 입력하도록 하자
이런식으로 스키마에서 사용할 DB가 굵게 표시가 되야한다.
# product table 생성
create table product(
id int auto_increment primary key,
title nvarchar(100),
price int,
image nvarchar(100)
);
# product tabble column 확인
desc product;
# product table data insert
insert into product(title,price,image) values('명태냉면1인분',8700,'/images/img01.jpg');
insert into product(title,price,image) values('오징어볶음1인분',8900,'/images/img02.jpg');
insert into product(title,price,image) values('채끝 찹스테이크',9100,'/images/img03.jpg');
insert into product(title,price,image) values('플랫브레드루꼴라피자1인분',8900,'/images/img04.jpg');
insert into product(title,price,image) values('불락전골1인분',10900,'/images/img05.jpg');
insert into product(title,price,image) values('닭볶음탕1인분',7800,'/images/img06.jpg');
insert into product(title,price,image) values('자장밥1인분',2800,'/images/img07.jpg');
insert into product(title,price,image) values('황태양념구이1인분',7800,'/images/img08.jpg');
# product table data 확인
SELECT
*
FROM
product;
- 입력한 DB data를 VSC에서 넣도록 하자.
/db.js
데이터베이스를 연동하는 방법은 두 가지가 있다. 첫 번째는 매번 데이터베이스의 커넥션을 얻어서 사용하는 방법이고, 두 번째는 커넥션 풀을 생성해 서 커넥션을 미리 생성한 후에 하나씩 꺼내서 사용하는 방법이다. 커넥션 생성 비용은 매우 크므로 가능하면 커넥션 풀을 사용하는 것이 좋다. 이 파 일에는 두 개의 함수가 있다. connect는 데이터베이스 커넥션 풀을 생성하는 함수이고, get은 생성한 커넥션 풀을 반환하는 함수이다. get 함수를 통해 풀을 반환받은 후에 데이터베이스에 질의를 실행할 수 있다.
[new] ex02>db.js
var mysql = require('mysql');
var conn;
exports.connect = function () {
conn = mysql.createPool({
connectionLimit: 100,
host: 'localhost',
user: 'shop',
password: 'pass',
database: 'shopdb'
});
}
exports.get = function () {
return conn;
};
app.js 하단에 이와 같이 입력한다.
// DB 연결 / ; 꼭대기 ./ ; 같은폴더 ../ ; 한단계 위
var db =require('./db',);
db.connect(function(){
if(err){
console.log('<DB ERROR>');
process.exit(1); // error 발생 시 exit
}else{
console.log('<Connected to the MySQL server>');
}
});
module.exports = app;
photos.js을 다음과 같이 수정한다. Mysql에서 data를 받아온다.
var express = require('express');
var router = express.Router();
var db = require('../db');
/* GET users listing. */
router.get('/', function(req, res) {
/* format like $,$$$ */
var sql ='select *, format(price,0) fmt from product order by price desc';
db.get().query(sql, [], function(err, rows){
if(err) return res.sendStatus(400);
res.status(200).json(rows);
});
});
module.exports = router;
제대로 됐으면 브라우저에서 아래와 같이 확인이 가능하다.
http://localhost:3000/photos/
- select tag option을 이용해서 정렬을 할 수 있는 tag를 만들어보자.
index.ejs
<h3>[라이언 MD의 추천상품]</h3>
<div style="width: 900px; padding-left: 50px; text-align: left;">
<select id="key">
<option value="id">상품등록순</option>
<option value="price desc">상품고가순</option>
<option value="price">상품저가순</option>
<option value="title">상품명순</option>
</select>
</div>
<div id="photos"></div>
<h3>[SNS 고객후기]</h3>
h3와 div id='photos' 사이에 div>select>option을 추가한다.
getLIst(); // *****
//정렬값을 변경할 경우
$('#key').on('change',function(){
getLIst();
});
script 맨 앞에 위 코드를 추가한다.
// 8(4*2)개의 상품이미지 출력 + option에서 key 값을 받아 data에 넣는다.
function getLIst(){
$.ajax({
type: 'get',
url: '/photos',
datatype: 'json',
data : {'key':$('#key').val()}, //*****
success: function (data) {
let str = '';
$(data).each(function () {
let id = this.id;
let image = this.image;
let title = this.title;
let price = this.fmt;
if (id <= 8) {
str += '<div class="box">';
str += `<img src="${image}" style="width:150px; height:150px"/>`; //*****
str += `<div class="title">${id} : ${title}</div>`
str += `<div class="price">${price}원</div>`
str += '</div>';
};
$('#photos').html(str);
})
}
})};
8개의 이미지를 출력해서 option 클릭으로 key값에 따라서 정렬하는 function getList()로 묶는다.
// 슬라이드로 이미지 출력
$.ajax({
type: 'get',
url: '/photos',
dataType: 'json',
data: {'key': 'id'}, //*****
success: function (data) {
let str = '';
$(data).each(function () {
let image = this.image;
images.push(image);
let id = this.id;
str += '<div class="item">';
str += `<img src="${image}" width="100"/>`;
str += `<div>${id}</div>`;
str += '</div>';
});
$('#foods').html(str);
}
});
슬라이드 이미지도 나올 수 있도록 data를 설정하도록 한다.
- 최종본
ex02>routes>notice.js
var express = require('express');
var router = express.Router();
/* GET users listing. */
router.get('/', function(req, res, next) {
res.send([
{id: 1, title:'자기의 일은'},
{id: 2, title:'스스로 하자'},
{id: 3, title:'알아서 척척'},
{id: 4, title:'스스로 어른'},
{id: 5, title:'와아아 아아'},
]);
});
module.exports = router;
ex02>routes>photos.js
var express = require('express');
var router = express.Router();
var db = require('../db');
/* GET users listing. */
router.get('/', function(req, res) {
var key = req.query.key;
var sql =`select *, format(price,0) fmt from product order by ${key}`;
db.get().query(sql, [], function(err, rows){
if(err) return res.sendStatus(400);
res.status(200).json(rows);
});
});
module.exports = router;
ex02>views>index.ejs
<!DOCTYPE html>
<html>
<head>
<title><%= title %></title>
<link rel='stylesheet' href='/stylesheets/style.css' />
<script src="http://code.jquery.com/jquery-3.1.1.min.js"></script>
</head>
<body>
<div id="container">
<div id="header">
<img src="http://placehold.it/140/140" width="140" height="140" id="image"/> <!--인터벌로 이미지 넣을곳-->
<img src="/images/download.jpg" width="750" />
</div>
<div id="content">
<h3>[라이언 MD의 추천상품]</h3>
<div style="width: 900px; padding-left: 50px; text-align: left;">
<select id="key">
<option value="id">상품등록순</option>
<option value="price desc">상품고가순</option>
<option value="price">상품저가순</option>
<option value="title">상품명순</option>
</select>
</div>
<div id="photos"></div>
<h3>[SNS 고객후기]</h3>
<div id="slider">
<!-- 실제 보여지는 부분-->
<div id="foods"></div> <!-- 이미지 집합-->
</div>
<div id="pagination">
<button id="prev" disabled><</button> <!-- < <-->
<button id="next">></button> <!-- > >-->
</div>
<h3>[공지사항]</h3>
<table id="tbl">
</table>
</div>
<div id="footer">
<h3>Copyright ICIA 이주성</h3>
</div>
</div>
</body>
<script>
getLIst();
//정렬값을 변경할 경우
$('#key').on('change',function(){
getLIst();
});
let page = 0;
//다음 버튼 클릭
$('#next').on('click', function () {
page++;
change();
});
//이전 버튼 클릭
$('#prev').on('click', function () {
page--;
change();
});
//슬라이드 버튼 이미지 이동
function change() {
$('#foods').animate({
left: -page * 110
}, 1000);
if (page == 0) $('#prev').attr('disabled', true);
else $('#prev').attr('disabled', false);
if (page == 3) $('#next').attr('disabled', true);
else $('#next').attr('disabled', false);
};
let images =[];
// 슬라이드로 이미지 출력
$.ajax({
type: 'get',
url: '/photos',
dataType: 'json',
data: {'key': 'id'}, //*****
success: function (data) {
let str = '';
$(data).each(function () {
let image = this.image;
images.push(image);
let id = this.id;
str += '<div class="item">';
str += `<img src="${image}" width="100"/>`;
str += `<div>${id}</div>`;
str += '</div>';
});
$('#foods').html(str);
}
});
let index=0;
$('#image').attr('src', images[index]);
setInterval(() => {
$('#image').attr('src',images[index % 5]);
index++;
}, 1500);
// 8(4*2)개의 상품이미지 출력 + option에서 key 값을 받아 data에 넣는다.
function getLIst(){
$.ajax({
type: 'get',
url: '/photos',
datatype: 'json',
data : {'key':$('#key').val()}, //*****
success: function (data) {
let str = '';
$(data).each(function () {
let id = this.id;
let image = this.image;
let title = this.title;
let price = this.fmt;
if (id <= 8) {
str += '<div class="box">';
str += `<img src="${image}" style="width:150px; height:150px"/>`; //*****
str += `<div class="title">${id} : ${title}</div>`
str += `<div class="price">${price}원</div>`
str += '</div>';
};
$('#photos').html(str);
})
}
})};
// 공지사항 출력하기
$.ajax({
type: 'get',
url: '/notice',
dataType: 'json',
success:function(data){
let str ='';
$(data).each(function(){
let id = this.id;
let title = this.title;
str += '<tr>'
str += `<td>${id} : ${title}</td>`
str += '</tr>'
});
$('#tbl').html(str);
}
})
</script>
</html>
ex02>app.js
var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
// [new]
var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');
app.use('/', indexRouter);
app.use('/users', usersRouter);
app.use('/photos', require('./routes/photos'));
app.use('/notice', require('./routes/notice'));
// catch 404 and forward to error handler
app.use(function(req, res, next) {
next(createError(404));
});
// error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
// [new]
// DB 연결 / ; 꼭대기 ./ ; 같은폴더 ../ ; 한단계 위
var db =require('./db',);
db.connect(function(){
if(err){
console.log('<DB ERROR>');
process.exit(1);
}else{
console.log('<Connected to the MySQL server>');
}
});
module.exports = app;
ex02>db.js
var mysql = require('mysql');
var conn;
exports.connect = function () {
conn = mysql.createPool({
connectionLimit: 100,
host: 'localhost',
user: 'shop',
password: 'pass',
database: 'shopdb'
});
}
exports.get = function () {
return conn;
};
'ICIA 수업일지' 카테고리의 다른 글
2021.08.06 수업일지 {MySQL, html, css, java script(jQuery), node.js} (0) | 2021.08.07 |
---|---|
2021.08.05 수업일지{html, css, java script(jQuery),MySql,node.js} (0) | 2021.08.07 |
2021.08.03 수업일지(MySQL, jQuery, node.js) (0) | 2021.08.07 |
2021.08.02 수업일지(HTML, CSS, JAVA SCRIPT,MySQL) (0) | 2021.08.07 |
2021.07.30 수업일지 (0) | 2021.07.31 |