Basic Layout

  • Add Header and Footer Partials
  • Include Semantic UI 
  • Add Simple Nav

 

1. header.ejs, footer.ejs

모든 페이지는 동일한 상단, 하단 메뉴 디자인을 가지므로, 개별 페이지마다 입력하기 보다는 header와 footer를 만들어 조립하는 형태로 만드는 것이 유지보수나 작업에 유리하다.

<!DOCTYPE> <!-- header.ejs -->
<html>
	<head>
		<title>Blog APP</title>
		<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.4.1/semantic.min.css">
		<link rel="stylesheet" type="text/css" href="/stylesheet/app.css">
	</head>
	<body>
		<div class="ui fixed inverted menu"> <!-- container와 같은 역할 -->
			<div class="ui container">	
				<div class="header item"><i class="code icon"></i>Blog Site</div>
					<a href="/" class="item">Home</a>
					<a href="/blogs/new" class="item">New Post</a>
			</div>	
		</div>
<!-- footer.ejs-->
<!-- 해당 프로젝트는 페이지 하단에 디자인이 없으므로 간단하게 body, html을 닫는 용도로 사용-->

	</body>
</html>

 

2. Semantic ui

해당 프로젝트에서는 semantic framework 를 사용하였다. 최신버전 및 doc는 https://semantic-ui.com/에서 확인 가능.

3. Cutomized css

<!-- 필요에 따라 수정하여 사용할 css-->
i.icon {
	font-size: 2em;
}

.container.main {
	margin-top: 7.0em;
}

#delete {
	display: inline;
}

 

Hi Everyone!
Please review the following notes so that you may continue the course without issue:

If you're having trouble with the EJS include syntax in the next lecture then please review the note from section 28 regarding the syntax change in version 3.0.1, you can find it here.

Meanwhile, in the next lecture Colt mentions a spacing problem with the navbar, but he doesn't resolve that issue in the same video.

This has caused some confusion among students, so I just wanted to let you know that he will resolve the overlapping navbar issue in the Blog App: NEW and CREATE video.

There's nothing you need to do, just be aware that the navbar issue isn't resolved right away and that he will correct it shortly thereafter in a later video.

-------
Thanks,
Ian

Lesson 312에서는 RESTful Route의 7가지 기능 중 INDEX에 대해 알아본다.

Name Path HTML Verb Purpose
INDEX /blogs GET List all blogs
New /blogs/new GET Show new blog form
Create /blogs POST Create a new blog, then redirect somewhere
Show /blogs/:id GET Show info about one specific blog
Edit /blogs/:id/edit GET Show edit form for one blog
Update /blogs/:id PUT Update a particular blog, then redirect somewhere
Destroy /blogs/:id DELETE Delete a particular blog, then redirect somewhere

INDEX는 서버에 특정 URL로 GET method request가 전달될 경우 모든 페이지를 보여주기 위한 목적으로 사용한다. 즉 특정 URL로 GET 요청이 들어올 경우 index 페이지로 이동한 후 DB에 저장된 모든 데이터를 보여준다.

 

1. 개발환경 설정

1) framework 설치

#npm init
: npm init(package.json 파일 생성 및 의존성 등의 정보를 기록하기 위해 생성

#npm install express mongoose body-parser --save
: 해당 프로젝트에 사용할 node express, mongoose, body-parser 들을 npm(Node Package Management)를 이용하여 설치하고, 의존성을 package.json에 자동 저장

 

2. app.js 

1) framework 초기화

const bodyParser = require("body-parser"),
express          = require("express"),
mongoose         = require("mongoose"),
app              = express();

2) App 설정

mongoose.connect("mongodb://localhost:27017/restful_blog_app", {useNewUrlParser: true, useUnifiedTopology: true}); //db가 없을 시 생성하므로, 동일한 db와 연결하는 한 이름은 중요하지 않다. 
app.get("view engine", "ejs"); // ejs 파일 확장자 없이 명시없이 사용 
app.use(express.static("public")); // custom stylesheet를 사용하기 위한 경로("public")
app.use(bodyParser.urlencoded({extended: true}));
app.listen(process.env.PORT || 3000, (){
console.log("REST Server is running");
};

3) Mongoose Schema 생성

const blogSchema = new mongoose.Schema({ // mongoose의 Schema 메소드를 상속받은 blogSchema 생성 
	title: String,
	image: String,
	body: String,
	created: {type: Date, default: Date.now} // 현재 시간을 출력
});

4) Schema 할당

: 3)에서 생성한 Schema가 mongoose method를 가질 수 있도록 상속시킨다. (mongoose가 가진 속성/기능을 사용하기 위함)

const Blog = mongoose.model("Blog", blogSchema); 

 

3. RESTful ROUTES

1) INDEX 생성

브라우저에서 "/blog"로 GET method 요청이 들어왔을 때 미리 만들어놓은 "index.ejs"를 렌더링하여 응답하고, DB에 저장된 데이터를 blogs라는 이름으로 "/index"로 전달한다.

app.get("/blogs", (req, res) => {
	Blog.find({}, (err, blogs) => {
		if(err){
			console.log(err)
		} else {
			res.render("/index", {blogs: blogs});
		}
	})
});

2) "/" redirect

1)의 경우에 "/blogs" 라는 url로 GET 요청이 들어왔을 경우에만 보여주므로, "/" 로 GET 요청이 들어왔을 때도 동일한 index 페이지를 보여줄 수 있도록 처리한다.

app.get("/", (req, res) => {
	res.redirect("/blogs");
};
<%- include("partials/header") %>

<h1><%= campground.name%></h1>

<img src="<%=campground.image%>">
<p> <%= campground.description %> </p>


<%- include("partials/footer") %>

309에서 각 RESTFUL Route 시 사용한 페이지별 ejs 파일을 다시 한번 정리한다.

 

309의 app.js에 작성된 RESTFUL Route에서 사용되는 페이지의 정보는 각각 아래와 같다.

name url verb description
INDEX /campgrounds GET Display a list of all dog
NEW /campgrounds/new POST Display  form to make a new dog
CREATE /campgrounds POST Add new dog to DB
SHOW /campgrounds/:id GET Show info about one dog

 

render에 사용되는 각각의 페이지는 DRY(Don't Repeate Yourself)를 적용하기 위해 [그림 1]과 같이 공통되는 부분을 header와 footer를 붙여 사용한다. 페이지가 복잡하여 메뉴가 많아지거나 디자인 할 요소가 많아질 경우 소스를 일일이 복사하여 사용하는 것보다 header와 foot에 디자인을 적용시킨 후 해당 파일만 불러와 사용할 경우 유지보수나 스크립트 작성 시 많은 시간을 절약할 수 있다. 

[그림 1] header 와 footer 적용
[그림 2] 모든 페이지에서 적용된 header와 footer

 

[그림 3] 실제로 사용한  header의 내용, title, bootstrap호출, 상단 메뉴바 및 개별 메뉴 등이 설정되어 있다. 
[그림 4] 실제 사용한 footer의 모습. 페이지 기준으로 하단에 사이트 정보, 회사 전화번호, 로고 등이 포함 될 경우 header처럼 디자인 적용 후 단순히 호출하여 사용 가능하다. 

 

[그림 5] 실제 네이버 footer의 모습. 만약 footer를 사용하지 않을 경우 페이지 하단의 메뉴, 정책, 디자인 등이 바뀔 경우 몇 백만의 페이지를 일일히 수정해야만 하지만 footer를 사용할 경우 파일 하나를 수정하여 모든 페이지에 적용/수정이 가능하다. 

 

1. header 및 footer 생성

1-1. header 생성

목적은 모든 페이지에 적용될 상단 메뉴를 디자인 한 후 개별 페이지에서 호출하기 위함이다.

경로 : views/partials/header.ejs

 

[그림 6] header.ejs의 실제 디자인

<!DOCTYPE html>
<html>
  <head>
	<title>Yelpcamp</title> <!-- 브라우저 상단의 페이지 타이틀 이름-->
	<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css"> <!-- bootsrapt CDN --> 
  </head>

  <body>
	<nav class="navbar navbar-default"> <!-- 페이지 상단에 메뉴바를 디자인을 위한 공간 할당(full witdth) -->
	  <div class=container-fluid"> <!-- navbar-default에서 좌우 각 15px 씩 padding을 준 container-->
		<div class="navbar-header">
		   <a class="navbar-brand" href="/">YelpCamp</a>
		</div>

		<div class="collapse navbar-collapse">
		   <ul class="nav navbar-nav navbar-right"> <!-- 페이지 우측 및 수평 배치를 위해 <ul><li>태그 사용-->
			<li><a href="/">Login</a></li>	
			<li><a href="/">Sign Up</a></li>
			<li><a href="/">Logout</a></li>
		   </ul>
		</div>
	  </div>
	</nav>

 

1-2. footer 생성

: 현재 레슨에서는 따로 페이지 하단 메뉴 및 디자인이 없으므로 단순히 <body>태그 및 <html> 태그를 마무리하는 소스만 입력한다.

경로 : views/partials/header.ejs

	</body>

</html>

 

 

2. INDEX 생성

해당 프로젝트에서 index 페이지는 db에 저장되어 있는 각각의 name, image를 화면에 출력해주는 역할을 한다. 작성된 index.ejs는 express를 통해 request를 요청한 client로 response 되며, 서버로부터 response를 받은 브라우저를 이를 해석하여 user가 볼 수 있도록 페이지를 출력한다.

[그림 6] 해당 프로젝트의 index 페이지(좌). 각 캐릭터는 db에 저장된 name, imageUrl을 이용하여 화면에 출력한다(우)

 

2-1. index.ejs 생성

<!-- partials/header.ejs를 불러온다-->
<%- include("partials/header") %>

<div class="container"> <!-- 해당 container는 모든 contents를 페이지 중앙에 위치시키기 위해 사용-->
	<header class="jumbotron"> <!-- 기능적으로 div와 동일하게 컨텐츠를 분할함. 하지만  semantic web에서는 해당 class의 내용은 강조된 내용으로 인식-->
		<div class="container"> <!-- <header> 태그 내의 컨텐츠만 따로 디자인하기 위해 추가적인 div 사용
			<h1>Welcome To YelpCamp!</h1>
			<p> View our hand-picked campgrounds from all over the world</p>
			<p>
                <!-- 강조되며 큰 사이즈 버튼 생성, 클릭 시 "/campgrounds/new"로 링크됨-->
                <a class="btn btn-primary btn-lg" href="/campgrounds/new">Add New Campground</a>
			</p>
		</div>
	</header>

	
	<div class="row text-center" style="display:flex; flex-wrap: wrap;"> <!-- 개별 데이터를 보여주는 컬럼의 텍스트 위치, 반응형 여부 설정 -->
    	<% campgrounds.forEacher((campground) => { %> <!-- 스크립트에서 돌아가므로 선언문 사용. app.js에서 allCampgrounds가 할당된 campgrounds를 forEach문으로 돌려 모든 데이터를 출력 --> 
        	<div class="col-lg-6 col-md-4 col-sm-3"> <!-- 페이지를 12등분 했을 때 각 1200px 이상= 6/12칸, 992px 이상 = 4/12칸, 768px 이상에 해당하는 grid 사이즈로 컬럼을 출력 -->
				<div class="thumbnail"> <!-- thumnail 사용-->
					<img src="<%=campground.image%>"> <!-- campground의 image value를 추출하여 이미지 출력-->
					<div class="caption"> <!-- <h4>에 출력된 이름을 사용-->
						<h4><%= campground.name %></h4>
					</div>
						<p>	<!-- campground에 추출한 id값을 이용하여 각 데이터의 상세페이지로 링크하는 버튼 추가-->x
							<a href="/campgrounds/<%= campground._id %>" class="btn btn-primary">More Info</a>
						</p>
				</div>
        	</div>
    	});%>
	</div>
</div>

 

3. NEW 생성

: name, imageURL, Descriptio을 전달받는 페이지를 생성한다. 

[그림 7] 데이터를 전달받아 DB에 저장하기 위한 form 페이지

 

3-1. new.ejs 생성

<%- include("partials/header")%>
<div class="container">
	<div class="row">
		<h1 style="text-align: center;">Create a New Campground</h1>
		<div style="width: 90%; margin: 125px auto;">
			
			<form action="/campgrounds" method="POST"> <!-- Submit 버튼 클릭 시 input 태그 내의 데이터들을 /campgrounds route로 POST method-형식으로 전달한다-->
				<div class="form-group">
					<input class="form-control" type="text" name="name" placeholder="name">
				</div>				
				<div class="form-group">
					<input class="form-control" type="text" name="image" placeholder="image">	
				</div>
				<div class="form-group">
					<input class="form-control" type="text" name="description" placeholder="description">	
				</div>
				<div class="form-group">				
					<button class="btn btn-lg btn-primary btn-block">Submit!</button>
				</div>
			</form>
			<a href="/campgrounds">Go back</a>
		</div>
	</div>

</div>
<%- include("partials/footer")%>

 

 

4. SHOW 생성

: index에서 특정 데이터에 대한 자세한 정보 및 원본 이미지를 출력한다.

[그림 8] 상단 URL에서 /campgrounds/에 있는 의미 숫자들은 mongodb에 저장된 하워드 왈로위치의 id 값이다(그림 6 우측 참조). id값은 자동으로 생성되며, 최소 개별 db에서 unique를 보장한다.

 

상세보기 페이지는 간단하게 개별 인물의 이름, 이미지, 설명만 추가한다.

 

<%- include("partials/header") %>
<h1><%= campground.name%></h1>

<img src="<%= campground.image%>">

<p><%= campground.description %> </p>

<%- include("partials/footer") %>

Add Mongoose

1. Install and configure mongoose

2. Setup campground model

3. Use campground model inside of our routes 

 

 

Show pages

1. Review the RESTFful routes we're seen so far

2. Add description to our campground model

3. Show db.collection.drop()

4. Add a show route/templates

 

RESTFUL ROUTES sample

name url verb description
INDEX /dogs GET Display a list of all dog
NEW /dogs/new GET Display  form to make a new dog
CREATE /dogs POST Add new dog to DB
SHOW /dogs/id GET Show info about one dog

 

<app.js>

const express = require("express"),
	app = express(),
	bodyParser = require("body-parser"),
	mongoose = require("mongoose");

// mongodb와 mongoose 연결하여 js로 mongodb 사용 가능하게 설정한다. 27017은 mongodb의 기본 포트
mongoose.connect("mongodb://localhost:27017/yelp_camp", {useNewUrlParser: true, useUnifiedTopology: true});

// bodyParser를 사용할 수 있도록 설정
app.set(bodyParser.urlencoded({extended: true}))

// view engine이란 node js에서 다양한 형태의 language를 사용 시 해당 langauge들을 문제없이 사용할 수 있도록 해준다
// ex) HTML5, JSP etc
app.use("view engine", "js")

// Shcema Setup. DB Schema를 다음과 같이 설정한다. 일종의 템플릿으로 아래의 형태로 key-vale를 가진다. 
// 기본적으로 해당 Schema를 사용할 경우 3개의 key-value pair를 가진다.
const campgroundSchema = new mongoose.Schema({
	name: String,
	image: String,
	description : String
})

// 위에서 선언한 형태의 Schema로 컴파일된 모델의 속성을 가진 Campground을 새로 선언한다.
const Campground = mongoose.model("Campground", campgroundSchema);



// RESTFUL Route를 각각의 목적에 따라 선언한다.
app.get("/campgrounds", (req, res) => {
	//DB에서 campgrounds 데이터를 조건없이({}) 조회(find)한다. 즉 모든 데이터 조회.
		// 조회를 위해 2개의 인자를 사용한다. (err 여부와 db에서 받은 모든 정보)
	Campground.find({}, (err, allCampgrounds) => {
		if(err){// err 발생 시 
			console.log(err); // 터미널에 err를 출력
		} else {	// err 없을 시
			res.render("index", {campgrounds: allCampgrounds}); //index.ejs에 campgrounds라는 이름으로 allCampgrounds를 대입한다.
		}
	})
});


//CREATE - 새로운 campground를 database에 생성 
app.post("/campgrouds", (req, res) => { // POST method가 /campgrounds route로 전달되면 
	const name = req.body.name;	// 요청한 body의 name = name 값을 const name에 할당
	const image = req.body.image; // 요청한 body에 name = image 값을 const image에 할당
	const desc = req.body.description; // 요청한 body에 name = description 값을 const description에 할당
	// 위의 name, image, desc를 하나의 obj에 저장한다. 사용할 형태는 campgroundSchema와 동일하므로 각각 key-vale 형태로 맞춰준다.
	const newCampground = {name: name, image: image, description: desc};

	// DB에 mongoose로 모델링한 새로운 데이터를 생성하고 저장한다.
	Campground.create(newCampground, (err, newlyCreated) => {
		if(err){ // err 발생 시 터미널에 내용 출력
			console.log(err)
		} else {
			res.redirect("/campgrounds"); // 정상 동작 시 "/campgounds"로 페이지를 redirect하여 저장된 값을 페이지에서 볼 수 있도록 한다. 
		}
	})
});


//NEW - 새로운 campground를 생성할 수 있는 form을 보여준다.
app.get("/campgrounds/new", (req, res) => {
	res.render("new.ejs");	// "/campgrouynds/new"로 GET method 요청이 서버로 들어오면 new.ejs를 렌더링 한 값을 클라이언트로 respose한다.
});


//SHOW - 상세페이지를 보여준다. "/campgrounds" 페이지는 현재 DB에 저장된 데이터를 한 페이지에 출력하므로, description을 보여주는 개별 페이지로 이동시킨다.
app.get("/campgrounds/:id", (req, res) => {
	// 주어진 id 값으로 db를 검색하고, 검색한 데이터를 특정 페이지에 출력한다. 
	Campground.findById(req.params.id, (err, foundCampground) =>{ //기본 메소드인 findById를 사용해 campgroundSchema로 모델링한 campground를 id로 조회한다.
		if(err){
			console.log(err)
		} else { // err가 없을 시 렌더링한 show.ejs 응답한다. 응답할 때 findById로 조회한 데이터인 foundCampground를 campground로 할당한다.
			res.render("show", {campground: foundCampground});
		}
	})
});

// "/"형태로 GET METHOD 요청이 들어오면 landing page를 보여준다. 해당 if - else if 형태처럼 포괄하는 Route인 "/"가 코드 위에 있을 경우 모든 페이지가 landing page를
// 응답받는 것을 조심해야 한다. "/campground, /campground/new 등의 url은 결국 "/" 의 하위 형태이기 때문에 해당 Route가 위에 있으면 "/"뒤의 campgound 등은 무시하고
// landing page로 모두 이동시키기 때문이다.
app.get("/", (req, res) => {
	res.render("landing");
})



// express 시 사용하는 기본 서버 설정 내용이다. 해당 코드는 3000포트를 사용할 때의 옵션이며, 정상 연결 시 console log가 출력된다.
app.listen(process.env.PORT || 3000, () =>{ 
	console.log("The Yelpcamp v2 server has been started");
});





 

rendering 시 사용하는 ejs 파일은 310에서 정리

mongodb와 mongoose 연동 시 발생한 에러 제거 방법

 

npm uninstall mongoose ; npm install --save mongoose@5.10.7
// 기존에 설치된 mongoose 삭제 ; @ 뒤의 버전으로 mongoose를 재설치

최신 버전은 https://mongoosejs.com/ 아래의 링크를 확인한다.

 

Mongoose ODM v5.10.7

Let's face it, writing MongoDB validation, casting and business logic boilerplate is a drag. That's why we wrote Mongoose. const mongoose = require('mongoose'); mongoose.connect('mongodb://localhost:27017/test', {useNewUrlParser: true, useUnifiedTopology:

mongoosejs.com

 

 

 

아래와 같이 기존에 사용하던 기능이 deprecated 되거나 port 관련 에러가 발생할 경우 mongoose.connect에 option을 부여한다.

mongoose.connect("mongodb://localhost:27017/yelp_camp", { useNewUrlParser: true, useUnifiedTopology: true});
// 27017은 mongodb에서 사용하는 port

 

 

(node:1159) DeprecationWarning: current URL string parser is deprecated, and will be removed in a future version. To use the new parser,
 pass option { useNewUrlParser: true } to MongoClient.connect.
(node:1159) DeprecationWarning: current Server Discovery and Monitoring engine is deprecated, and will be removed in a future version. T
o use the new Server Discover and Monitoring engine, pass option { useUnifiedTopology: true } to the MongoClient constructor.

 

 

이번 lecture에서 할 작업은 아래와 같다. 

1. 305. Introduction to Mongoose Pt. 1에서 호출한 cats.js에 mongoose 모델링 생성

2. JS를 통해 mongdb에 실제로 데이터 저장 

3. 저장된 데이터를 retrieve(조회) 

4. 2번 최적화 코드

 

 

1. mongoose 모델링 생성 및 데이터 저장

cats.js

const mongoose = require("mongoose");
mongoose.connection("mongodb://localhost/cats_app", { useNewUrlParser: true}) 
// mongodb 서버가 동작 중일 때는 연결, 동작중이지 않을 때는 서버 구동 후 연결

const catSchema = new mongoose.Schema({
	name: String,
	age: Number,
	temperament: String
});

const Cat = mongoose.model("Cat", catSchema); 
// "Cat"이라는 이름의 catSchema 모델로 컴파일한 후 Cat 변수에 저장한다. 이는 데이터를 7번 라인에 선언한 
// 형태로 저장하기 위함이다. 

// Adding a new cat to the DB
// db에 george를 저장하기 위해 변수 생성
const george = new Cat({
	name: "george",
	age: 11,
	temperament: Grouchy
});

george.save((err, cat) => {
	if(err){
		console.log("Something has went wrong!");
	} else {
		console.log("We've just save a CAT to the db");
		console.log(cat);		// 실제 db에 저장된 cat를 console log로 출력
		console.log(george);	// 19라인에서 저장된 george를 console.log로 출력
	}
});

 

[그림 1] mongoDB에 실제로 저장된 후 console log에 찍힌 메세지

하지만 실제로 console log에 찍힌 값은 db에서 조회된 데이터가 아닌 저장 시 db에 전달한 값일 뿐이다.

 

 

2. db에 저장된 데이터를 실제로 조회

cats.js

const mongoose = require("mongoose");
mongoose.connection("mongodb://localhost/cats_app", { useNewUrlParser: true}) 
// mongodb 서버가 동작 중일 때는 연결, 동작중이지 않을 때는 서버 구동 후 연결

const catSchema = new mongoose.Schema({
	name: String,
	age: Number,
	temperament: String
});

const Cat = mongoose.model("Cat", catSchema); 
// "Cat"이라는 이름의 catSchema 모델로 컴파일한 후 Cat 변수에 저장한다. 이는 데이터를 7번 라인에 선언한 
// 형태로 저장하기 위함이다. 

// Adding a new cat to the DB
// db에 george를 저장하기 위해 변수 생성
const george = new Cat({
	name: "george",
	age: 11,
	temperament: Grouchy
});

george.save((err, cat) => {
	if(err){
		console.log("Something has went wrong!");
	} else {
		console.log("We've just save a CAT to the db");
		console.log(cat);		// 실제 db에 저장된 cat를 console log로 출력
		console.log(george);	// 19라인에서 저장된 george를 console.log로 출력
	}
});



// DB에 저장된 모든 값을 조회한다. 
Cat.find({}, (err, cats) => {
	if(err){
		console.log("Oh no, Error has been occured!");
        console.log(err);
	} else {
		console.log("All the cats are... ");
		console.log(cats);
	}
});


 

3. 1에서 george라는 변수에 고양이의 데이터를 저장한 후, 그 데이터를 다시 db로 전달하였다. 이를 하나의 코드로 작성한다.

 

cats.js

const mongoose = require("mongoose");
mongoose.connection("mongodb://localhost/cats_app", { useNewUrlParser: true}) 
// mongodb 서버가 동작 중일 때는 연결, 동작중이지 않을 때는 서버 구동 후 연결

//const catSchema = new mongoose.Schema({
//	name: String,
//	age: Number,
//	temperament: String
//});

const Cat = mongoose.model("Cat", catSchema); 
// "Cat"이라는 이름의 catSchema 모델로 컴파일한 후 Cat 변수에 저장한다. 
// 이는 데이터를 7번 라인에 선언한 형태로 저장하기 위함이다. 

// Adding a new cat to the DB
// db에 george를 저장하기 위해 변수 생성
//const george = new Cat({
//	name: "george",
//	age: 11,
//	temperament: Grouchy
//});

//george.save((err, cat) => {
//	if(err){
//		console.log("Something has went wrong!");
//	} else {
//		console.log("We've just save a CAT to the db");
//		console.log(cat);		// 실제 db에 저장된 cat를 console log로 출력
//		console.log(george);	// 19라인에서 저장된 george를 console.log로 출력
//	}
//});


Cat.create({			// catSchema로 작성된 Cat이란 변수에 아래의 값을 추가한다.
	name: "Korean short",
	age: 2,
	temperament: "cute"
	}, (err, newCat) => {
		if(err){
			console.log(err);
		} else {
			console.log(newCat);
		}
})


// DB에 저장된 모든 값을 조회한다. 
Cat.find({}, (err, cats) => {
	if(err){
		console.log("Oh no, Error has been occured!");
        console.log(err);
	} else {
		console.log("All the cats are... ");
		console.log(cats);
	}
});


 

[그림 2] cats.js 구동 시 console log에 출력되는 내용. 2개의 george 중 1개는 실제 db로 저장되는 값, 나머지 1개는 저장하기 위해 JS로 변환시켜놓은 값이다. 

 

[그림 3] mongoDB에 실제로 저장된 데이터 

 

Mongoose란?

: Mongoose provides a straight-forward, schema-based solution to model your application data. It includes built-in type casting, validation, query building, business logic hooks and more, out of the box.(mongoosejs.com/)

 

 

Mongoose를 사용하는 이유

: Mongoose를 사용하여 Javascript와 MongoDB를 연결하여 사용할 수 있다. 즉 Javascript 코드를 통해 CRUD(Create, Read, Update, Delete) 가능하다.

 

Mongoose 설치 

: # npm install mongoose 

 

[그림 1] Installation of the mongoose

 

Javascript에서 mongoose 사용 방법

const mongoose = require("mongoose"); //mongoose 패키지 로드
mongoose.connect("mongodb://localhost/cat_app", { userNewUrlParser: true}); // mongoose와 mongdb를 연결한다.

const catSchema = new mongoose.Schema({ 
// DB에 사용될 schema를 정의한다. 아래와 같이 3개의 Key-Value 쌍을 가진 데이터를 생성
	name: String,
	age: Number,
	temperament: String
});   

const Cat = mongoose.model("Cat", catSchema); 
//catSchema를 mongoDB 모델로 컴파일한다. 즉 위에서 선언된 catSchema 각각의 Key-Value 모델을 Cat에 저장하여
// mongo shell 에서 사용하듯 작업할 수 있는 모델로 변경한다. 

+ Recent posts