[Node.js] TypeORM๋ก CRUD ๊ตฌํํด ๋ณด๊ธฐ (feat. MySQL)
์๋ ํ์ธ์ Foma ์ ๋๋ค.
์ ๋ฒ ๊ธ์์ TypeORM์ด ๋ฌด์์ธ์ง์ ๋ํด ๋ค๋ค ๋ณด์๋๋ฐ์.
์ด๋ฒ ๊ธ์์ TypeORM์ผ๋ก ์์ฑ, ์กฐํ, ์ญ์ , ์์ ์ ๋ค๋ค๋ณด๋ ๋ฒ์ ๋ํด์ ์์ฑํด ๋ณด๋ ค๊ณ ํฉ๋๋ค.
๋ฐ๋ก ์์ํ ๊ฒ์~
Init TypeORM
์ฐ์ typeORM์ ์ฌ์ฉํ๊ธฐ ์ํด์ ์์ฑํ ํ๋ก์ ํธ ํด๋์ typeorm ๋ชจ๋์ ์ค์นํด ์ฃผ์ ์ผ ํฉ๋๋ค.
npm install typeorm -g
์๋์ ๊ฐ์ด typeorm ํ๋ก์ ํธ๋ฅผ ์์ฑํด ์ค๋๋ค.
typeorm init --name ํ๋ก์ ํธ ์ด๋ฆ --database ์ฌ์ฉํ ๋ฐ์ดํฐ๋ฒ ์ด์ค
๊ทธ๋ฌ๋ฉด ์๋์ ๊ฐ์ด ํด๋น ๊ฒฝ๋ก์ ํ๋ก์ ํธ๊ฐ ์์ฑ๋ ๊ฒ์ ๋ณผ ์ ์์๊ฑฐ์์.
ํด๋น ํ๋ก์ ํธ๋ฅผ VSCode๋ก ์ผ๋ณด๋ฉด ์๋์ ๊ฐ์ด ๋ช ๊ฐ์ง ํด๋์ ํ์ผ์ด ๋ฏธ๋ฆฌ ์์ฑ๋์ด ์๋ ๊ฒ์ ๋ณผ ์ ์์ต๋๋ค.
Set a data-source
data-source.ts
ํด๋น ํ์ผ์ ๋ฐ์ดํฐ ๋ฒ ์ด์ค๋ฅผ ์ฐ๊ฒฐ ์ ๋ณด๋ฅผ ์ค์ ํด ์ฃผ๋ ๊ณต๊ฐ์ ๋๋ค.
import "reflect-metadata";
import { DataSource } from "typeorm";
import { Chat } from "./entity/Chat";
import { User } from "./entity/User";
export const AppDataSource = new DataSource({
type: "mysql",
host: "localhost",
port: 3306,
username: "์ ์ ๋ค์",
password: "ํจ์ค์๋",
database: "๋๋น์ด๋ฆ",
synchronize: true,
logging: false,
entities: [User, Chat],
migrations: [],
subscribers: [],
});
Create entities
๋จผ์ ์ ๋ User์ Chat ๋ชจ๋ธ์ ๋ง๋ค์ด ์ฃผ๋๋ก ํ๊ฒ ์ต๋๋ค.
User.ts
@Entity() => ํด๋น Entity์ ๋ํ ์ ๋ณด๋ฅผ ์ ํจ.
@PrimaryGeneratedColumn() => Primary ํค์ ์๋์ผ๋ก ์์ฑ๋๋ ์ปฌ๋ผ์ ์๋ฏธํจ.
@Column() => ์ผ๋ฐ์ ์ธ ์ปฌ๋ผ์ ์๋ฏธํ๋ฉฐ ๊ดํธ ์ฌ์ด์ ์ ์ฝ ์กฐ๊ฑด ๋ฑ์ ์ถ๊ฐํ ์ ์์.
@OneToMany() => ์ผ๋๋ค ๊ด๊ณ๋ฅผ ๋งบ๋ ๊ฒ์ ์๋ฏธํจ. ex) ํ ์ ์ ์ ๋ชจ๋ ์ฑํ ์ ๊ด๊ณ ๋งบ์.
import { Entity, PrimaryGeneratedColumn, Column, OneToMany } from "typeorm";
import { Chat } from "./Chat";
@Entity({ name: "users" })
export class User {
@PrimaryGeneratedColumn("uuid")
id: string;
@Column({ type: "varchar", length: 10 })
firstName: string;
@Column({ nullable: false })
lastName: string;
@Column()
age: number;
@OneToMany(() => Chat, (chat) => chat.user)
chats: Promise<Chat[]>;
}
Chat.ts
@ManyToOne() => ๋ค๋์ผ ๊ด๊ณ๋ฅผ ๋งบ๋ ๊ฒ์ ์๋ฏธํจ. ex) ๋ชจ๋ ์ฑํ ์ ํ ์ ์ ์ ๊ด๊ณ๋ฅผ ๋งบ์.
import { Entity, PrimaryGeneratedColumn, Column, ManyToOne } from "typeorm";
import { User } from "./User";
@Entity({ name: "chats" })
export class Chat {
@PrimaryGeneratedColumn("uuid")
id: string;
@Column({ type: "varchar", length: 100 })
content: string;
@ManyToOne(() => User, (user) => user.chats)
user: Promise<User>;
}
Create a controller
์ ์ ์ปจํธ๋กค๋ฌ๋ฅผ ๋ง๋ค์ด ์์ฑ, ์กฐํ, ์ญ์ , ์์ ๋ฉ์๋๋ฅผ ๋ง๋ค์ด ์ฃผ๊ฒ ์ต๋๋ค.
import { AppDataSource } from "../data-source";
import { Chat } from "../entity/Chat";
import { User } from "../entity/User";
import { Request, Response } from "express";
export default class UserController { ...
Create(Insert)
firstName,lastName,age๋ฅผ ์์ฒญ์ผ๋ก๋ถํฐ ๋ฐ์ User ๋ ํฌ์งํ ๋ฆฌ์ ๋ฃ์ด์ค๋๋ค.
addUser = async (req: Request, res: Response) => {
let info = {
firstName: req.body.firstName,
lastName: req.body.lastName,
age: req.body.age,
};
const userRepo = AppDataSource.getRepository(User);
const user = userRepo.create(info);
await userRepo
.save(user)
.then((data) => {
res.json(data);
})
.catch((err) => console.log(err));
};
Read(Get)
์์ฒญ์ ํ๋ผ๋ฏธํฐ์ firstName์ ๊ฐ์ง ์ ์ ๋ฅผ ์กฐํํด ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ต๋๋ค.
getUser = async (req: Request, res: Response) => {
let name = req.params.firstName;
const userRepo = AppDataSource.getRepository(User);
await userRepo
.findOne({ where: { firstName: name } })
.then((data) => {
res.json(data);
console.log("Get User: ", data);
})
.catch((err) => console.log(err));
};
Read(Get)
๋ชจ๋ ์ ์ ๋ฅผ ๊ฐ์ ธ์ต๋๋ค.
getAllUsers = async (req: Request, res: Response) => {
const userRepo = AppDataSource.getRepository(User);
await userRepo
.findAndCount()
.then((data) => {
res.json(data);
console.log("Get all User: ", data);
})
.catch((err) => console.log(err));
};
Update
์์ฒญ์ ํ๋ผ๋ฏธํฐ์ firstName์ ๊ฐ์ง ์ ์ ์ ์ ๋ณด๋ฅผ ์์ฒญ์ body๋ก ์์ ํด ์ค๋๋ค.
updateUser = async (req: Request, res: Response) => {
const userRepo = AppDataSource.getRepository(User);
await userRepo
.createQueryBuilder()
.update(User)
.set(req.body)
.where({ firstName: req.params.firstName })
.execute()
.then((data) => {
res.json(data);
console.log("Update User: ", data);
})
.catch((err) => console.log(err));
};
Delete
์์ฒญ์ ํ๋ผ๋ฏธํฐ์ firstName์ ๊ฐ์ง ์ ์ ๋ฅผ ์ญ์ ํด ์ค๋๋ค.
deleteUser = async (req: Request, res: Response) => {
const userRepo = AppDataSource.getRepository(User);
await userRepo
.createQueryBuilder()
.delete()
.from(User)
.where({ firstName: req.params.firstName })
.execute()
.then((data) => {
res.json(data);
console.log("Delete User: ", data);
})
.catch((err) => console.log(err));
};
Set a router
UserController ๊ธฐ๋ฐ์ผ๋ก ๋ผ์ฐํฐ๋ฅผ ๋ง๋ค์ด ์ค๋๋ค.
import * as express from "express";
import UserController from "../controllers/UserController";
const userRouter = express.Router();
let userController = new UserController();
userRouter.post("/addUser", userController.addUser);
userRouter.get("/user/:firstName", userController.getUser);
userRouter.get("/allUsers", userController.getAllUsers);
userRouter.put("/user/:firstName", userController.updateUser);
userRouter.delete("/user/:firstName", userController.deleteUser);
export default userRouter;
Run the server
index.ts
userRouter๋ฅผ express app์ ์ธํ ํด์ฃผ๊ณ ํฌํธ๋ฅผ 3000๋ฒ์ผ๋ก ์คํ ์์ผ์ค๋๋ค.
import { AppDataSource } from "./data-source";
import * as express from "express";
import userRouter from "./routers/UserRouter";
const app = express();
app.use(express.json());
AppDataSource.initialize()
.then(async () => {})
.catch((error) => console.log(error));
app.use("/api", userRouter);
app.listen(3000, () => {
console.log("Server running");
});
Test
addUser
//POST
http://localhost/api/addUser
//JSON
{
"firstName":"foma",
"lastName":"gran",
"age":27
}
getUser
//GET
http://localhost/api/user/foma
getAllUsers
//GET
http://localhost/api/allUsers
updateUser
//PUT
http://localhost/api/user/foma
//JSON
{
"firstName":"fomaaa",
"lastName":"grannnn",
"age":27
}
deleteUser
//DELETE
http://localhost/api/user/fomaaa