First cooperation project
์ฌ๋ฌ๋ถ์ ๋์ฅ๊ณ ๋ ํ์ฌ ์ด๋ค ์ํ์ธ๊ฐ์? ๊ฐ์ง๊ณ ์๋ ์์ฌ๋ฃ๋ก ์ด๋ค ์๋ฆฌ๋ฅผ ํ ์ง ๊ณ ๋ฏผ์ด ๋๊ฑฐ๋ ๋๋ ์ํ์ง ์์ฌ๋ฃ๊ฐ ์์ง๋ ์๋์?
์ด๋ฌํ ๊ณ ๋ฏผ์ ๊ฐ์ง 5๋ช ์ ํ์๋ค์ด ์ ์ํ Refri Bank๋ ๋์ฅ๊ณ ๋ฅผ ์๋ฏธํ๋ Refrigerator์ ๊ด๋ฆฌ๋ฅผ ๋์ ์ํํ๋ Bank๋ฅผ ํฉ์น ๋จ์ด์ ๋๋ค.
์ฒ์์ ๋จ์ํ ๋์ฅ๊ณ ์ ๋ค์ด์๋ ์์ฌ๋ฃ๋ฅผ ์ฌ์ฉํ ์์๋ ๋ ์ํผ ์ถ์ฒ ์๋น์ค๋ฅผ ๊ตฌ์ํ์์ผ๋, ์ถ๊ฐ์ ์ผ๋ก ์ ํฌ๊ฐ ๊ฐ์ง ๋ฐ์ดํฐ๋ฅผ ์ด์ฉํ์ฌ ์ค์๊ฐ ์ธ๊ธฐ ๋ ์ํผ, ๋ด๊ฐ ๋ฑ๋กํ ์์ฌ๋ฃ์ ์ ํต๊ธฐํ, ์ฌ๋ฃ๋ ์ ๋ชฉ์ ํตํ ๋ ์ํผ ๊ฒ์๊ธฐ๋ฅ, ์์ ๊ฒ์ํ ๋ฑ์ ๋ง๋ค์ด ์ต๋ํ ๋ค์ํ ์๋น์ค๋ฅผ ์ ๊ณตํ ์ ์๋๋ก ์ ์ํ์์ต๋๋ค.
์ด์ ์ค์๊ฐ์ผ๋ก ์ธ๊ธฐ์๋ ๋ ์ํผ, ํน์ ๊ถ๊ธํ ๋ ์ํผ๋ฅผ ๊ฒ์ํด๋ณด์ธ์! ๋ง์ฝ ํ์๊ฐ์ ์ ํ์๋ฉด ๋์ฅ๊ณ ํ์ด์ง์์ ์์ฌ๋ฃ์ ์ ํต๊ธฐํ์ ํ์ํ ์์๊ณ , Refri Bank๋ ๋์ฅ๊ณ ์ ๋ค์ด์๋ ์์ฌ๋ฃ๋ฅผ ๋ฐํ์ผ๋ก ํ์ฌ ์ถ์ฒ ๋ ์ํผ๋ฅผ ์ ๊ณตํด์ค๋๋ค.
๐ Communication
๐ ๋ชจ๋ ํ์๋ค์ด ํ์
๊ฒฝํ์ด ๋จ ํ๋ฒ๋ ์กด์ฌํ์ง ์์, trouble์ด ์์ฃผ ๋ฐ์ํ์๋ค.
๋ณ์๋ช
๊ท์น์ ์งํค์ง ์๊ฑฐ๋, git collision์ด ๋งค์ฐ ์์ฃผ ๋ฐ์ํ์๊ณ , ํ๋ก์ ํธ ๋ง๊ฐ ์ผ์๊ฐ ๋ค๊ฐ์ฌ ์๋ก ์๋ก ๋ง์ด ๋คํฌ๊ธฐ๋ ํ์๋ค.
๋คํด์๋ ์์ผ๋, ๊ฐ์ ์ด ์ํด ์์ผ๋ก์ ์์
์ ์ํฅ์ ์ฃผ๋ ๊ฒ์ ๋ฌธ์ ๊ฐ ๋ ์์์๊ธฐ์, ๋๋ ํ๋ฃจ์ ์์
์ด ๋๋๊ณ ๊ฐ์ ๋ค๋ฅธ ํ์๋ค์ ์นญ์ฐฌํ๋ ์นญ์ฐฌํ๋ ์๊ฐ์ ๋ง๋ค์๊ณ , ๊ฒฐ๊ณผ์ ์ผ๋ก ๋ฌด์ฌํ ํ๋ก์ ํธ๋ฅผ ๋ง์น ์์์๋ค.
๐ Crawling
๐ ํด๋จน๋จ๋
๋ผ๋ ์ฌ์ดํธ์์ Crawling์ ํ์ฉํ์ฌ ํด๋จน๋จ๋
์ฌ์ดํธ๋ฅผ Crawling ํ์๋ค.
ํด๋จน๋จ๋ ์ฌ์ดํธ๋ ๋ ์ํผ์ ๋ํ ๋ง์ ์ ๋ณด๋ฅผ ์ ๊ณตํ๋๋ฐ, ์ฐ๋ฆฌ๊ฐ ํ์๋ก ํ๋ ๋ฐ์ดํฐ๋ ๋จ์ํ๋ค. ์ฌ๋ฃ, Kcal, ์กฐ๋ฆฌ ์๊ฐ, ๋ ์ํผ ์ ๋ณด๋ค์ด์๋ค. Crawling์ ๋ด๋นํ๋ ์น๊ตฌ๊ฐ Crawling Logic์ ๊ณ ๋ฏผํ๊ณ ์์๊ณ , ๋๋ ์ฌ๊ท๋ฌธ์ ์์ฑํ์ฌ ์ ์์ ์ผ๋ก ์ํ๋ ๋ฐ์ดํฐ๋ง ๋ฝ์์ฌ ์์์๋ค.
์ด ๋ฐ์ดํฐ๋ฅผ ์ด์ฉํ์ฌ Recipe PK์ ๋ฐ๋ฅธ REST API๋ฅผ ์ ์กํด์ฃผ์๋ค.
๐ GetRecipe Method
๐ ์๋์ ํ๋ฉด์์ ๋ณด์ด๋ ๋ฐ์ดํฐ๋ฅผ ๋ณด๋ด์ฃผ๊ธฐ ์ํด ๋ชจ๋ Recipe๋ฅผ ๊ฐ์ ธ์ค๋ Method๊ฐ ํ์ํ๊ณ , Method์ ๋ํ ๊ณ ๋ฏผ์ด ํ์ํ๋ค.
Method์ ์ฌ์ฉ๋ query๋ ์๋์ ๊ฐ๋ค.
const mainpage_request = {
GetFoodMain : async (req,res)=>{
const req_get_foodmain = new MainClass(req.body);
const res_get_foodmain = await req_get_foodmain.GetFoodMain();
return res.json(res_get_foodmain);
}
}
class MainSql {
static async GetFoodMain(req) {
return new Promise((resolve, reject) => {
const query = "SELECT * FROM FoodMain WHERE FoodN LIKE '%"+req.id+"%' ORDER BY likeit DESC";
db.query(query ,(err, data) => {
if (err) reject(`${err}`)
resolve(data);
});
});
}
}
ํ๋ฒ์ ๋ชจ๋ ๋ฐ์ดํฐ๋ฅผ ๋ถ๋ฌ์ค๊ธฐ์ ๊ต์ฅํ ๋นํจ์จ์ ์ฒ๋ผ ๋ณด์ธ๋ค. ํ์ง๋ง, ๋ฐ์ดํฐ๊ฐ ๊ทธ๋ฆฌ ๋ง์ง ์๊ธฐ ๋๋ฌธ์ ์์ฐ์ฑ์ ๋์ด๊ธฐ ์ํ์ฌ ๋ชจ๋ ๋ฐ์ดํฐ๋ฅผ ๋ถ๋ฌ์ค๋ query๋ฌธ์ ์์ฑํ์๋ค.
๐ Like Method
๐ ์๋์ ํ๋ฉด์ ๋ณด๋ฉด, ๋ ์ํผ๋ณ๋ก ์ข์์๊ฐ ๋ง์ ์์๋๋ก ์ถ์ฒ ๋ ์ํผ๋ฅผ ๋ณด์ฌ์ค๋ค. ์ด๋ฅผ์ํด, ๋ ์ํผ์ ์ข์์๋ฅผ ํ์ํ ์์๋ ๋ฒํผ์ด ํ์ํ๊ณ , ์ด ๊ฐ์ DB์ ์ ์ฅํด์ผ ํ๋ค.
Like Method์ ๋ํ ์๊ตฌ ์ฌํญ์ ์๋์ ๊ฐ๋ค.
- Like button์ ๋ํ ์ทจ์๋ ๋ค๋ฅธ ํ์ด์ง์์ ์งํํ ์์์
- ํน์ Recipe์ Like๋ฅผ ๋๋ฅธ User๋ ๋ Like๋ฅผ ๋๋ฅผ ์์์
User์ Recipe๋ N:N ๊ด๊ณ์ด๋ค. ๋ฐ๋ผ์ DB ๊ตฌ์กฐ๋ ์๋์ ๊ฐ์ด ๊ตฌ์ฑํ์๋ค.
N : 1, 1 : N์ผ๋ก ๊ด๊ณ๋ฅผ ํ์ด ํน์ Recipe์ ์ข์์๋ฅผ ๋๋ฅธ User ์ ๋ณด๋ฅผ ๊ด๋ฆฌํ์๋ค.
์ด๋ ์ฌ์ฉ๋ Method์ query๋ ์๋์ ๊ฐ๋ค.
const recipe_request = {
AddLike : async (req, res) => {
const req_add_like = new RecipeClass(req.body);
const res_add_like = await req_add_like.AddLike();
return res.json(res_add_like);
}
}
class RecipeSql {
static async AddLike(req) {
return new Promise((resolve, reject) => {
const squery = "SELECT * FROM likeit WHERE userid = (?) and foodid = (?) ";
const lquery = "UPDATE FoodMain SET likeit = likeit+1 WHERE FoodId = (?);";
const uquery = "INSERT INTO likeit(foodid, userid, foodname) VALUES(?, ?, ?);";
db.query(squery, [req.userid, req.id], (err, length) => {
if (err) reject(`${err}`);
else if (length.length < 1) {
db.query(lquery, [req.id], (err, data) => {
if (err) reject(`${err}`);
else {
db.query(uquery, [req.id, req.userid, req.foodname], (err, check) => {
if (err) reject(`${err}`);
resolve({ success: true });
})
}
});
}
else {
resolve({ success: false })
}
});
});
}
}
๐ shopping basket method.
๐ ์๋์ ๊ทธ๋ฆผ๊ณผ ๊ฐ์ด User๊ฐ ์ฌ๋ฃ๋ฅผ ์ ํํ์ฌ ๋๋ง์ ๋์ฅ๊ณ ์ ๋ฃ์ ์์๋ค.
์ฅ๋ฐ๊ตฌ๋์ ์ฌ๋ฃ๋ฅผ ๋ฃ์ ๋ค, submit button์ ๋๋ฅด๋ฉด, ์ด ์ฌ๋ฃ์ ๋ฐ๋ผ ๋ ์ํผ๋ฅผ ์ถ์ฒํด์ค๋ค.
submit button์ ๋๋ฅด๋ฉด, User๊ฐ ์ถ๊ฐํ Ingredient๊ฐ Update ๋์ผ ํ๊ณ , ์ฌ์ฉํ ์ฟผ๋ฆฌ๋ฌธ์ ์๋์ ๊ฐ๋ค.
static async UpdateRFG(user) {
return new Promise(async (resolve, reject) => {
const delete_query = "DELETE FROM UserRfg WHERE ID=(?)";
const insert_query = "INSERT INTO UserRfg(ID, Igdname, Eprdate) VALUES(?, ?, ?);";
db.query(delete_query, [user.id], (err) => {
if (err) reject(`${err}`);
else {
db.query(insert_query, [user.id, user.igdname, user.eprdate], (err) => {
if (err) reject(`${err}`);
else resolve({ success: true });
});
}
});
});
}
UserRfg๋ User๊ฐ ๊ฐ์ง๊ณ ์๋ Ingredient์ ๋ํ Table์ด๋ค. ์ฌ๊ธฐ์ ๊ธฐ์กด์ UserRfg์ ์ ์ฅํ๊ณ ์๋ Ingredient๋ฅผ ์ฅ๋ฐ๊ตฌ๋์ ์ ์ฅํ๊ณ , ๊ธฐ์กด์ ์ ์ฅํ๊ณ ์๋ Ingredient๋ ์ ๋ถ DELETEํ๋ค. ๊ทธํ, ํ์ฌ ์ฅ๋ฐ๊ตฌ๋์ ๋ค์ด์๋ Ingredient๋ฅผ ๋ค์ UserRfg์ ์ถ๊ฐํ๋ ๋ฐฉ์์ผ๋ก ๊ตฌํํ์๋ค.
Ingredient์ ๋ฐ๋ผ Recipe๋ฅผ ์ถ์ฒํด์ฃผ๊ธฐ ์ํ Ingredient๊ฐ ํ์ํ๋๋ฐ, ์ฅ๋ฐ๊ตฌ๋์ ๋ค์ด์๋ ๋๋คํ Ingredient 1๊ฐ๋ฅผ ๊ธฐ์ค์ผ๋ก ์ถ์ฒํ์๋ค.
์ฌ์ฉํ ์ฟผ๋ฆฌ๋ฌธ์ ์๋์ ๊ฐ๋ค.
class RfgSql {
static async GetIgdrc(req) {
return new Promise((resolve, reject) => {
const query = "SELECT * FROM FoodMain WHERE FoodId IN (SELECT FoodId FROM FoodIgd WHERE IgdN1 LIKE '%" + req.igd + "%' OR IgdN2 LIKE '%" + req.igd + "%' OR IgdN3 LIKE '%" + req.igd + "%' OR IgdN4 LIKE '%" + req.igd + "%' OR IgdN5 LIKE '%" + req.igd + "%' OR IgdN6 LIKE '%" + req.igd + "%' OR IgdN7 LIKE '%" + req.igd + "%' OR IgdN8 LIKE '%" + req.igd + "%' OR IgdN9 LIKE '%" + req.igd + "%' OR IgdN10 LIKE '%" + req.igd + "%' OR IgdN11 LIKE '%" + req.igd + "%' OR IgdN12 LIKE '%" + req.igd + "%' OR IgdN13 LIKE '%" + req.igd + "%' OR IgdN14 LIKE '%" + req.igd + "%' OR IgdN15 LIKE '%" + req.igd + "%')"
db.query(query, (err, data) => {
if (err) reject(`${err}`);
resolve(data);
});
});
}
}
์ฟผ๋ฆฌ๋ฌธ์ ํ๋์ฝ๋ฉ ํ์๋ค. ๋ชจ๋ ๋ ์ํผ๋ Ingredient๊ฐ์๊ฐ ๋ฌ๋๋ค. ์ด๋ค ๊ฒ์ 30๊ฐ๊ฐ ๋์ด๊ฐ๊ธฐ๋ ํ๊ณ ์ด๋ค๊ฒ์ 10๊ฐ ์ดํ์ด๊ธฐ๋ ํ๋ค. ๋ฐ๋ผ์ Crawling์ ์งํํ ๋ Ingredient๋ฅผ ์ต๋ 15๊ฐ๋ง ๊ฐ์ ธ์ค๊ธฐ๋ก ๊ฒฐ์ ํ์๊ณ , Ingredient Column์ 15๋ก ๊ณ ์ ์ด ๋์์ผ๋ฉฐ, ๊ฒฐ๊ณผ๋ฌผ์ ์๋์ ๊ฐ๋ค.
๐ Recipe Likeit Method
๐ ์๋์ ๊ทธ๋ฆผ๊ณผ ๊ฐ์ด User๋ Likeit button์ ๋๋ฅธ ๋ ์ํผ๋ฅผ ๋ณผ ์์๋ค.
Recipe์ User๋ N:N ๊ด๊ณ์ด๊ธฐ ๋๋ฌธ์ ์ด๋ฅผ ํ์ด๋ธ Likeit table์ ์ด์ฉํ์ฌ ์ด๋ฅผ ๊ตฌํํ์์ผ๋ฉฐ, ์ญ์ method๋ ๋ง์ฐฌ๊ฐ์ง์ด๋ค. ์ฌ์ฉํ ์ฟผ๋ฆฌ๋ฌธ์ ์๋์ ๊ฐ๋ค.
static async Deletelikeit(req) {
return new Promise((resolve, reject) => {
const delete_likeit = "DELETE FROM likeit WHERE foodid=(?) and userid=(?);"
db.query(delete_likeit, [req.number, req.userid], (err, length) => {
if (err) reject(`${err}`);
else {
resolve({ success: true })
}
})
});
}
}
class Mypagesql {
static async likeitpage(user){
return new Promise(async (resolve, reject) => {
const query = "SELECT * FROM likeit WHERE userid = (?)"
db.query(query,[user.id], (err,data) => {
if (err) reject(`${err}`);
else resolve({data});
});
});
}
}
๐ Board
๐ Board ๊ธฐ๋ฅ์ ๋จ์ CRUD๋ง์ผ๋ก ๊ตฌํํ์๊ณ , ๋๊ธ์ board_id, user_id๋ฅผ ์ ์ฅํ๋ Reply table์ ๊ตฌ์ฑํ์ฌ N:N ๊ด๊ณ๋ฅผ ํ์ด๋๋ค.
๊ฒฐ๊ณผ๋ฌผ๊ณผ ์ฌ์ฉํ ์ฟผ๋ฆฌ๋ฌธ๋ค์ ์๋์ ๊ฐ๋ค.
////////Reply////////
static async AddReply(req) {
console.log(req);
return new Promise((resolve, reject) => {
const query = "INSERT INTO Reply(number, userid, nickname, description, created) VALUES(?, ?, ?, ?, ?);"
const ucount = "UPDATE freeboard SET count = count + 1 WHERE number =(?);"
db.query(query, [req.number, req.userid, req.nickname, req.description, req.created], (err, data) => {
console.log(req.created)
if (err) reject(`${err}`);
db.query(ucount, [req.number], (err) => {
if (err) reject(`${err}`);
resolve(data);
});
});
});
}
static async GetReply(req) {
return new Promise((resolve, reject) => {
const query = "SELECT * FROM Reply WHERE number=(?);"
db.query(query, [req], (err, data) => {
if (err) reject(`${err}`);
resolve(data);
});
});
}
- communication
๋๊ตฐ๊ฐ์๊ฒ ๋์ ์ฃผ์ฅ์ ํผ์น๊ธฐ ์ํด์๋ ๊ทผ๊ฑฐ๊ฐ ํ์ํ๋ค๋ ๊ฒ์ ๋ฐฐ์ฐ๊ฒ ๋์๋ค. - SQL ์ค์ฌ์ ์ธ ๊ฐ๋ฐ์ ๋ฌธ์ ์
์ด ํ๋ก์ ํธ๋ SQL์ ๊ต์ฅํ ์์กด์ ์ด๋ค. ์ด๋ SQL ์ค์ฌ์ ์ธ ๊ฐ๋ฐ์ ๋ฌธ์ ์ ์ ๋๋ผ๊ฒ ๋์๊ณ , ํ์ ORM์ ๊ณต๋ถํ๋ฉด์ ์ด์๋ํด ๋ธ๋ก๊ทธ์ ์ ๋ฆฌํ์๋ค.
https://blog.naver.com/ds4ouj/222682683072 - ํจ์จ์ฑ
ํธ๋ํฝ์ ์๊ฐํ์ง ์๊ณ , ์๋ฒ ๊ฐ๋ฐ์ ํ๋ค๋ ๋ฌธ์ ์ ์ ์๊ฒ๋์๋ค.