Merge branch 'feature/220524_nodejs_orm_model' into 'main'
Feature/220524 nodejs orm model # nodejs 서버 유저 및 키워드 database connection 및 모델 생성 및 쿼리 함수 ## database connection 1. Sequelize ORM 사용하여 db connection ## Model 1. User model 생성 2. Keyword model 생성 3. User-Keyword many to many 관계 생성 ## Query - addKeyword - 키워드 추가 함수 `INPUT: {keyword, userId}` - 유저 id 기반으로 키워드 추가 및 연결 테이블 레코드 생성 - deleteKeyword - 키워드 삭제 함수 `INPUT: {userId, keyword}` - 유저 id 기반으로 연결 테이블 레코드 삭제 - getKeywordsByUserId - 유저가 등록한 키워드 조회 함수 `INPUT: {userId}` - 유저 id 기반으로 연결된 모든 키워드 조회 - getUsersByKeyword - 키워드를 등록환 유저 조회 함수 `INPUT: {keyword}` - 키워드 기반으로 연결된 모든 유저 조회 - getAllUsers - 등록된 모든 유저 조회 함수 `INPUT: {NONE}` - getAllKeywords - 등록된 모든 키워드 조회 함수 `INPUT: {NONE}` See merge request !17
Showing
8 changed files
with
246 additions
and
1 deletions
server/apis/database.js
0 → 100644
1 | +let database = module.exports = {}; | ||
2 | + | ||
3 | +const db = require("../models") | ||
4 | +const User = db.user | ||
5 | +const Keyword = db.keyword | ||
6 | +const UserKeyword = db.userKeyword | ||
7 | + | ||
8 | + | ||
9 | +database.addKeyword = async function(keyword, userId) { | ||
10 | + | ||
11 | + const u = await User.findOrCreate({ | ||
12 | + where: { | ||
13 | + userId: userId | ||
14 | + } | ||
15 | + }) | ||
16 | + | ||
17 | + const k = await Keyword.findOrCreate({ | ||
18 | + where: { | ||
19 | + keyword: keyword | ||
20 | + } | ||
21 | + }) | ||
22 | + | ||
23 | + await UserKeyword.findOrCreate({ | ||
24 | + where: { | ||
25 | + userId: u[0].id, | ||
26 | + keywordId: k[0].id | ||
27 | + } | ||
28 | + }) | ||
29 | +} | ||
30 | + | ||
31 | +database.deleteKeyword = async function(userId, keyword) { | ||
32 | + | ||
33 | + const u = await User.findOrCreate({ | ||
34 | + where: { | ||
35 | + userId: userId | ||
36 | + } | ||
37 | + }) | ||
38 | + | ||
39 | + const k = await Keyword.findOrCreate({ | ||
40 | + where: { | ||
41 | + keyword: keyword | ||
42 | + } | ||
43 | + }) | ||
44 | + | ||
45 | + await UserKeyword.destroy({ | ||
46 | + where: { | ||
47 | + userId: u[0].id, | ||
48 | + keywordId: k[0].id | ||
49 | + } | ||
50 | + }) | ||
51 | +} | ||
52 | + | ||
53 | +database.getKeywordsByUserId = async function(userId) { | ||
54 | + | ||
55 | + const keywords = await Keyword.findAll({ | ||
56 | + attributes: ['keyword'], | ||
57 | + where: { | ||
58 | + '$user.userId$': userId | ||
59 | + }, | ||
60 | + include: [{ | ||
61 | + attributes: [], | ||
62 | + model: User, | ||
63 | + as: 'user' | ||
64 | + }], | ||
65 | + raw: true | ||
66 | + }) | ||
67 | + | ||
68 | + let result = [] | ||
69 | + for (let i = 0; i < keywords.length; i++) { | ||
70 | + result.push(keywords[i].keyword) | ||
71 | + } | ||
72 | + | ||
73 | + return result | ||
74 | +} | ||
75 | + | ||
76 | +database.getUsersByKeyword = async function(keyword) { | ||
77 | + | ||
78 | + const users = await User.findAll({ | ||
79 | + attributes: ['userId'], | ||
80 | + where: { | ||
81 | + '$keyword.keyword$': keyword | ||
82 | + }, | ||
83 | + include: [{ | ||
84 | + attributes: [], | ||
85 | + model: Keyword, | ||
86 | + as: 'keyword' | ||
87 | + }], | ||
88 | + raw: true | ||
89 | + }) | ||
90 | + | ||
91 | + let result = [] | ||
92 | + for (let i = 0; i < users.length; i++) { | ||
93 | + result.push(users[i].userId) | ||
94 | + } | ||
95 | + | ||
96 | + return result | ||
97 | +} | ||
98 | + | ||
99 | +database.getAllUsers = async function() { | ||
100 | + | ||
101 | + const users = await User.findAll({ | ||
102 | + raw: true | ||
103 | + }) | ||
104 | + | ||
105 | + let result = [] | ||
106 | + for (let i = 0; i < users.length; i++) { | ||
107 | + result.push(users[i].userId) | ||
108 | + } | ||
109 | + | ||
110 | + return result | ||
111 | +} | ||
112 | + | ||
113 | +database.getAllKeywords = async function() { | ||
114 | + | ||
115 | + const keywords = await Keyword.findAll({ | ||
116 | + raw: true | ||
117 | + }) | ||
118 | + | ||
119 | + let result = [] | ||
120 | + for (let i = 0; i< keywords.length; i++) { | ||
121 | + result.push(keywords[i].keyword) | ||
122 | + } | ||
123 | + | ||
124 | + console.log(result) | ||
125 | + return result | ||
126 | +} | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
... | @@ -3,13 +3,35 @@ const line = require("@line/bot-sdk"); | ... | @@ -3,13 +3,35 @@ const line = require("@line/bot-sdk"); |
3 | const setFlexMessage = require("./apis/setFlexMessage"); | 3 | const setFlexMessage = require("./apis/setFlexMessage"); |
4 | const fs = require("fs"); | 4 | const fs = require("fs"); |
5 | 5 | ||
6 | +const { sequelize } = require('./models') | ||
7 | +const database = require("./apis/database"); | ||
8 | + | ||
9 | +// Initialize DB connection | ||
10 | +sequelize.sync({ force: false }) | ||
11 | + .then(() => { | ||
12 | + console.log('database connection complete'); | ||
13 | + database.addKeyword("rtx3060", "junseok") | ||
14 | + database.getKeywordsByUserId("junseok") | ||
15 | + database.deleteKeyword("phobyjun", "rtx3080") | ||
16 | + database.getAllUsers() | ||
17 | + database.getUsersByKeyword("rtx3060") | ||
18 | + database.getAllKeywords() | ||
19 | + }) | ||
20 | + .catch((err) => { | ||
21 | + console.log('database connection failed'); | ||
22 | + }); | ||
23 | + | ||
24 | +// Load .env configuration | ||
6 | require("dotenv").config(); | 25 | require("dotenv").config(); |
7 | const config = { | 26 | const config = { |
8 | channelAccessToken: process.env.channelAccessToken, | 27 | channelAccessToken: process.env.channelAccessToken, |
9 | channelSecret: process.env.channelSecret, | 28 | channelSecret: process.env.channelSecret, |
10 | }; | 29 | }; |
11 | 30 | ||
31 | +// Express app server initialization | ||
12 | const app = express(); | 32 | const app = express(); |
33 | + | ||
34 | +// Create post request handler for chatbot | ||
13 | app.post("/webhook", line.middleware(config), (req, res) => { | 35 | app.post("/webhook", line.middleware(config), (req, res) => { |
14 | Promise.all(req.body.events.map(handleEvent)).then((result) => | 36 | Promise.all(req.body.events.map(handleEvent)).then((result) => |
15 | res.json(result) | 37 | res.json(result) | ... | ... |
server/config/config.json
0 → 100644
1 | +{ | ||
2 | + "development": { | ||
3 | + "username": "root", | ||
4 | + "password": "mamuri", | ||
5 | + "database": "mamuri_db", | ||
6 | + "host": "127.0.0.1", | ||
7 | + "dialect": "mysql" | ||
8 | + }, | ||
9 | + "test": { | ||
10 | + "username": "root", | ||
11 | + "password": null, | ||
12 | + "database": "database_test", | ||
13 | + "host": "127.0.0.1", | ||
14 | + "dialect": "mysql" | ||
15 | + }, | ||
16 | + "production": { | ||
17 | + "username": "root", | ||
18 | + "password": null, | ||
19 | + "database": "database_production", | ||
20 | + "host": "127.0.0.1", | ||
21 | + "dialect": "mysql" | ||
22 | + } | ||
23 | +} |
server/models/index.js
0 → 100644
1 | +'use strict'; | ||
2 | + | ||
3 | +const fs = require('fs'); | ||
4 | +const path = require('path'); | ||
5 | +const Sequelize = require('sequelize'); | ||
6 | +const basename = path.basename(__filename); | ||
7 | +const env = process.env.NODE_ENV || 'development'; | ||
8 | +const config = require(__dirname + '/../config/config.json')[env]; | ||
9 | +const db = {}; | ||
10 | + | ||
11 | +let sequelize; | ||
12 | +if (config.use_env_variable) { | ||
13 | + sequelize = new Sequelize(process.env[config.use_env_variable], config); | ||
14 | +} else { | ||
15 | + sequelize = new Sequelize(config.database, config.username, config.password, config); | ||
16 | +} | ||
17 | + | ||
18 | +fs | ||
19 | + .readdirSync(__dirname) | ||
20 | + .filter(file => { | ||
21 | + return (file.indexOf('.') !== 0) && (file !== basename) && (file.slice(-3) === '.js'); | ||
22 | + }) | ||
23 | + .forEach(file => { | ||
24 | + const model = require(path.join(__dirname, file))(sequelize, Sequelize.DataTypes); | ||
25 | + db[model.name] = model; | ||
26 | + }); | ||
27 | + | ||
28 | +Object.keys(db).forEach(modelName => { | ||
29 | + if (db[modelName].associate) { | ||
30 | + db[modelName].associate(db); | ||
31 | + } | ||
32 | +}); | ||
33 | + | ||
34 | +db.sequelize = sequelize; | ||
35 | +db.Sequelize = Sequelize; | ||
36 | + | ||
37 | +db.user = require("./user")(sequelize, Sequelize); | ||
38 | +db.keyword = require("./keyword")(sequelize, Sequelize); | ||
39 | +db.userKeyword = sequelize.define('user_keywords'); | ||
40 | + | ||
41 | +db.user.belongsToMany(db.keyword, {through: db.userKeyword, as: 'keyword'}); | ||
42 | +db.keyword.belongsToMany(db.user, {through: db.userKeyword, as: 'user'}); | ||
43 | + | ||
44 | +module.exports = db; |
server/models/keyword.js
0 → 100644
1 | +module.exports = (sequelize, DataTypes) => { | ||
2 | + | ||
3 | + return sequelize.define("keyword", { | ||
4 | + id: { | ||
5 | + type: DataTypes.INTEGER, | ||
6 | + autoIncrement: true, | ||
7 | + primaryKey: true | ||
8 | + }, | ||
9 | + keyword: { | ||
10 | + type: DataTypes.STRING, | ||
11 | + allowNull: false | ||
12 | + } | ||
13 | + }) | ||
14 | +} | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
server/models/user.js
0 → 100644
1 | +module.exports = (sequelize, DataTypes) => { | ||
2 | + | ||
3 | + return sequelize.define("user", { | ||
4 | + id: { | ||
5 | + type: DataTypes.INTEGER, | ||
6 | + autoIncrement: true, | ||
7 | + primaryKey: true | ||
8 | + }, | ||
9 | + userId: { | ||
10 | + type: DataTypes.STRING, | ||
11 | + allowNull: false | ||
12 | + } | ||
13 | + }) | ||
14 | +} | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
This diff is collapsed. Click to expand it.
... | @@ -18,6 +18,8 @@ | ... | @@ -18,6 +18,8 @@ |
18 | "@line/bot-sdk": "^7.5.0", | 18 | "@line/bot-sdk": "^7.5.0", |
19 | "dotenv": "^16.0.1", | 19 | "dotenv": "^16.0.1", |
20 | "express": "^4.18.1", | 20 | "express": "^4.18.1", |
21 | - "nodemon": "^2.0.16" | 21 | + "mysql2": "^2.3.3", |
22 | + "nodemon": "^2.0.16", | ||
23 | + "sequelize": "^6.20.0" | ||
22 | } | 24 | } |
23 | } | 25 | } | ... | ... |
-
Please register or login to post a comment