반응형

Update

export const videoEditSave: ExpressRouter = async (req, res) => {
	const { id } = req.params;
	const { title, description, hashTags } = req.body;
	const videoId = id.replace("/edit", "");
	const video = await contentsModel.exists({ _id: videoId });

	if (!video) {
		return res.render("404", {
			pageTitle: `Not Found`,
		});
	}
	await contentsModel.findByIdAndUpdate(videoId, {
		title,
		description,
		hashTags: hashTags.split(",").map((word: string) => `#${word}`),
	});

	return res.redirect(`/video`);
};

 

- Mongoose - Pre

Pre는 새로운 객체를 저장할때 저장하기전 스키마의 행위를 지정해주는 미들 웨어이다.

예를 들면 해쉬태그를 작성한다면 input의 값을 쉼표로 나누어 작성했을 경우 하나의 객체로 만들어주며 하나의 객체 앞에 '#'을 붙여주는 행위를 한다 가정했을 때 아래와 같이 문장을 작성할 수 있다. 

Pre에는 두가지 인자를 받는데 첫번 째로는 방식이며 지정되어 있다. 두번째는 function을 입력해주면 된다.

contentsSchema.pre("save", async function () {
	this.hashTags =
		this.hashTags &&
		(this.hashTags[0] as string).split(",").map((word) => `#${word}`);
});

 

- Mongoose - Static

Static은 Pre와 비슷하지만 직접 function handler를 만들어준다고 생각하면 쉽다.

 

contentsSchema.static('hashFormat', function(hashTags){
	return hashTags.split(",").map((word:string) => `#${word}`)
})

 

//type script 경우에
import mongoose, { Model } from "mongoose";
import { IVideo } from "../types/type";
interface IHashformat extends Model<IVideo> {
	formatHash(hashTags: string): string[];
}
const contentsSchema = new mongoose.Schema<IVideo, IHashformat>({
	contentsForm: { type: String, required: true, trim: true },
	title: { type: String, required: true, trim: true, minLength: 3 },
	description: { type: String, required: true, trim: true, maxLength: 30 },
	createAt: { type: Date, required: true, default: Date.now() },
	hashTags: [{ type: String, trim: true }],
	meta: {
		views: { type: Number, required: true, default: 0 },
		rating: { type: Number, required: true, default: 0 },
	},
});


contentsSchema.static(
	"formatHash",
	function formatHash(hashTags: string): string[] {
		return hashTags.split(",").map((word: string) => `#${word}`);
	},
);
const contentsModel = mongoose.model<IVideo, IHashformat>(
	"Video",
	contentsSchema,
);
export default contentsModel;

 

Delete

export const deleteVideo: ExpressRouter = async (req, res) => {
	const { id } = req.params;
	const videoId = id.replace("/delete", "");
	const video = await contentsModel.exists({ _id: videoId });
	if (video) {
		await contentsModel.findByIdAndDelete(videoId);
		res.redirect("/video");
	} else {
		return res.render("404", {
			pageTitle: `Not Found`,
		});
	}
};

 

 

728x90
반응형

CRUD

이제 데이터베이스와 함께 사용하기 앞서 이를 활용하기 위해 CRUD를 먼저 이해할 필요가 있다.

CRUD는 아래의 약어로 이루져 있다. 

  • Create
  • Read
  • Update
  • Delete

Post와 Get을 활용한 데이터 통신을 하나 씩 이루어 나갈 것이다.

 

CRUD를 활용하기 위해서 일단 데이터의 model을 설정해주어야한다.

현재 mongoDB와 mongoose를 사용하기 때문에 mongoose로 mongoDB에게 우리가 어떤 데이터를 사용하고 있는지 알려줘야한다.

그러기에 앞서 우리의 데이터가 어떤것을 가지고 있고 어떤 타입을 지정해줘야할지 고민해 볼필요가 있다. 이런 생김새를 보통 Schema라고 한다.

Mongoose Schema & Export  Model

타입정의도 가능하며 유효성도 체크도 가능하며 디폴트 값을 줘 문장을 간소화도 할수있다. 

import mongoose from "mongoose";

const videoSchema = new mongoose.Schema({
	title: String,
	description: { type: String, required: true },
	createAt: { type: Date, required: true, default: Date.now() },
	hashTags: [{ type: String }],
	meta: {
		views: Number,
		rating: Number,
	},
});

const videoModel = mongoose.model("Video", videoSchema);
export default videoModel;

 

 

보내질 데이터를 어떤 모습으로 보내줄건가에 대한 것은 schema에 담고 이 schema model이름은 Video로 지어 import할 수 있게 만들어준다. 그리고 이를 사용하기 위해 server에 import 해준다.

 

Schema Type

https://mongoosejs.com/docs/schematypes.html

 

Mongoose v8.0.3: SchemaTypes

SchemaTypes SchemaTypes handle definition of path defaults, validation, getters, setters, field selection defaults for queries, and other general characteristics for Mongoose document properties. You can think of a Mongoose schema as the configuration obje

mongoosejs.com

 

Using Model 

Export한 videoModel을 사용하고자하는 Controller에 import를 해주자

https://mongoosejs.com/docs/queries.html

 

Mongoose v8.0.3: Queries

Queries Mongoose models provide several static helper functions for CRUD operations. Each of these functions returns a mongoose Query object. A mongoose query can be executed in one of two ways. First, if you pass in a callback function, Mongoose will exec

mongoosejs.com

위의 문서를 보고 관련된 메소드를 찾아 문장을 구성해주면 된다.

export const video = async (req, res) => {
	const videos = await videoModel.find({});
	return res.render("./videoTemp/video", { pageTitle: "VIDEO", videos });
};

 

Create Models

try catch 문을 사용하면 더 좋다.

생성을 하게되면 생성한 object는 고유 id가 저절로 제공이 된다!

https://www.mongodb.com/docs/manual/reference/method/ObjectId/

export const uploadPost: ExpressRouter = async (req, res) => {
	const { contentRadio, contentTitle, contentDesc, contentHashTags } = req.body;
	if (contentRadio === "video") {
		// const video = new videoModel({
		// 	title: contentTitle,
		// 	description: contentDesc,
		// 	hashTags: contentHashTags.split(",").map((tags: string) => `#${tags}`),
		// 	createAt: Date.now(),
		// 	meta: {
		// 		views: 0,
		// 		rating: 0,
		// 	},
		// });
		// await video.save();
		await videoModel.create({
			title: contentTitle,
			description: contentDesc,
			hashTags: contentHashTags.split(",").map((tags: string) => `#${tags}`),
			createAt: Date.now(), // schema에 default값을 주면 생략 가능
			meta: {
				views: 0,
				rating: 0,
			},
		});
	}

	return res.redirect("/");
};
728x90
반응형

Database

데이터베이스에 데이터를 올리기 위해서는 일단 Get과 Post에 대해 알아야한다. 이를 위해서 html의 form을 이용해서 POST를 보내주어야한다.

이를 이해하기 위해 Fake data base를 만들어보자

// Data
const videos: IContentsModel[] = [
	{
		id: 1,
		title: "hoho",
		desc: "fhj",
		createAt: new Date().toLocaleDateString(),
	},
	{
		id: 2,
		title: "heeh",
		desc: "werte",
		createAt: new Date().toLocaleDateString(),
	},
	{
		id: 3,
		title: "hahah",
		desc: "ryftujkty",
		createAt: new Date().toLocaleDateString(),
	},
	{
		id: 4,
		title: "asdf",
		desc: "asfdasdf",
		createAt: new Date().toLocaleDateString(),
	},
];

그리고 front를 만들어주어 back으로 보낼 준비를 해주자. 여기서 중요한 것은 form의 메소드를 POST로 설정해주어야한다. 만약 url의 설정을 바꾸고 싶다면 action attribute를 주어 url도 설정할 수 있으나 같은 url주소로 POST를 할꺼니 action은 따로 지정하지 않았다.

extends ../layout/layout
block contents 
    div 
        form(method="POST") 
            legned(hidden) EDIT #{video.title}
            label(for="videoTitle") EDIT #{video.title}
            input#videoTitle(type="text", name="title" value=video.title) 
            input(type="submit" value="submit")

 

해당 화면을 볼수 있게 라우터와 controller middleware를만들어준다.

 movieRouter.get("/:id([0-9]/edit)", videoEdit);
export const videoEdit: ExpressRouter = (req, res) => {
	const { id } = req.params;
	const videoId = +id.replace("/edit", "") - 1;
	const video = videos[videoId];
	return res.render("./videoTemp/videoEdit", {
		pageTitle: `EDIT ${video.title.toUpperCase()}`,
		video,
	});
};

POST를 위한 Router를 만들어준다.

movieRouter.post("/:id([0-9]/edit)", videoEditSave);

 

 

movieRouter.get("/:id([0-9]/edit)", videoEdit);
movieRouter.post("/:id([0-9]/edit)", videoEditSave);

 

router 설정에 get 과 post를 한 줄로 정리할 수 있는데

movieRouter.route("/:id([0-9]/edit)").get(videoEdit).post(videoEditSave);

로 축약할 수 있다.

 

그리고 POST의 controller middleware 설정을 해주면 끝

export const videoEditSave: ExpressRouter = (req, res) => {
	const { id } = req.params;
	const { title } = req.body;
	const videoId = +id.replace("/edit", "");
	const video = videos[videoId - 1];
	video.title = title;
	return res.redirect(`/video/${videoId}`);
};

 

MongoDB

mongoDB는 다목적이고 document(문서) 기반으로 작동한다. 보통 database는 문서기반이 아니다 sql 기반이다. 엑셀시트 같은 개념이다. mongoDB에서 DB는 object로 움직인다. 행으로 저장이 되지않고 Array Object들로 구성이 된다. JSON처럼 저장된다는 느낌이라고 생각하면 된다.

Install

MongoDB Community Server를 다운 받아준다. 

Connecting

Mongoose

mongoose는 NodeJS와 MongoDB를 이어주는 매개체가 될것이다. mongo가 잘 설치 되었는지 확인하기 위해 터미널에 아래의 명령어를 입력해준다. not found 문구가 나오면 다시 설치해야한다.

mongod

그리고 아래 입력

mongosh
mongosh 명령어

help
show dbs
db.

 

VScode로 돌아와서 mongoose 설치

npm install mongoose --save

mongoDB와 연결해주기 위해 코드를 작성해야한다. src 폴더에 db.ts or js를 생성

import mongoose from "mongoose";
//mongosh에 나와있는 connecting to 참조
mongoose.connect("mongodb://로컬호스트:포트넘버/임의 저장소 이름을 지정",{});

백엔드 파일에가서 db.ts or js 파일 자체를 import를 해주어야한다. 경고나 주의가 터미널창에 나오면 ,{} 안에 터미널창에 나오는 데로 작성해주면 된다.

연결의 성공 여부나 에러를 console.log로 출력하기 위해 다음과 같이 문장을 추가한다.

mongoose.connection.once("connected", () => console.log("✅ DB is connected"));
mongoose.connection.on("error", (error) => console.log(error));
728x90

+ Recent posts