usestate

>> let [글제목, b] = useState(['내용1', '내용2', ...]);

 

Warning 메세지는 앱을 실행하는데에는 큰 문제가 없는 메세지이다. 이를 없애는 방법은 코드의 맨 위에

/* eslint-disable */ 

를 사용하면 된다 (Lint 기능을 끈다.)

 

- 좋아요 버튼& 갯수 UI 만들기

좋아요 옆에 들어가는 숫자를 state로 만들자

let [좋아요, c] = useState(0);

 

클릭했을때 원하는 기능을 실행하기 위해선 onClick을 사용하면된다. 이를 보통 이벤트 리스너라고 한다.

onClick은 태그 바로 옆에 선언해서 사용할 수 있다. onClick = {함수이름}을 넣어서 사용할 수 있다.

 함수 이름 안에 그냥 함수를 넣어도 된다. ( function()이나 ()=>를 넣어도 된다.)

- state를 변경하는 법

좋아요 = 좋아요 + 1 등호를 이용해 바꿀 수  없다.

이럴때는 state 변경 함수를 써야한다.

state를 변경하면 html이 재랜더링이 된다.

이를 사용하는 방법은 따봉변경(원하는 기능 적기)

위의 경우에는

이렇게 하면 좋아요 이모티콘을 누를때마다 이모티콘 옆의 숫자가 증가한다.

 

state를 변경할때는 무조건 변경함수를 이용해야한다.

 

array object state 변경하는법

이런 방법으로 글제목을 바꿀 수 있다 하지만 이렇게 사용하면 확장성이 부족함으로 

위와 같이 인덱싱 방법으로 하는 것이 더 빠르다. 

하지만 array나 object를 다룰 때는 원본을 보존하는 것이 좋기 때문에 원본은 보존하는 것이 좋다. 그렇기 때문에 내용을 수정할 복사본을 따로 만들어 사용할 수 있다.

여기서 복사본 [...글제목]에서 글제목 앞에 ...을 붙여서 위와 같이 만들어야만 변경이 된다. 

이렇게 해야하는 두가지 이유가 있는데

첫 번째는 기존 state의 값과 신규 state의 값이 같을 경우 변경을 해주지 않는 state 변경함수의 특징 때문이다. 

두 번째는 array/object 담을때 다음과 같이 let arr = [1, 2, 3] 처럼 지정할 경우 1,2,3을 가리키는 주소만 지정되기 때문에 내용이 바뀌지 않는다 그렇게 때문에 ...을 사용해야지 데이터를 직접 수정할 수 있다.

 

여기서 글제목은 array 데이터가 아니라 그 저장 공간의 주소 혹은 위치를 가르키는 화살표라고 생각할 수 있다.

그래서 copy == 글제목을 비교하면 항상 같다고 나온다.

 

결론적으로 ...은 괄호를 벗기고 그 안의 데이터를 가져오는 것이다.

 

 

아니!!! aws 결제 수단 등록이 계속 안되서 그냥 네이버 클라우드 플랫폼 사용하기로 했다

빠르게 회원가입 한 후에 결제 수단을 등록한 후에 바로 이용할 수 있다.

그후 콘솔로 들어간 후 클래식으로 바꾸고 서비스를 눌러서 서버로 들어간다.

서버생성을 누르고 서버를 만든다 

그리고 공인 ip를 만들어준다

이후 서버를 이용하기 위해 putty를 다운받는다

그리고 푸티를 열어서 연 서버를 입력한다. IP주소는 공인 ip를 만든 후에 공인 ip를 Host Name에 적어준 후 Saved Sessions에 원하는 서버 이름을 적고 save를 한 후에 open한다.

이렇게 하면 서버에 접속을 할 수 있다. 브라우즈를 해서 다운받은 키를 가져오고 session으로 돌아가 저장을 하면 된다.

 

저장이 됐는지 확인하기 위해서 자신의 서버 이름을 로드 한 후 브라우즈한 키가 유지되는지 확인하면 된다. 그 후 open을 한다.

 

여기서 주의할 점은 인증키를 puttyzen에서 ppk 파일로 바꿔줘야 사용할 수 있다.

 

바꿔준 후에 open을 누르고 ubuntu를 누르면 비밀번호를 입력하라고 나온다 이를 확인하기 위해선 네이버 클라우드에서 아래와 같이 서버 관리 및 설정 변경에서 관리자 비밀 번호 확인을 통해 비밀번호를 가져와야한다. 

확인하는 법은 아래와 같이 관리자 비밀번호 확인을 누르고 인증키로 받은 pem 파일을 넣어준후 확인할 수 있다.

 

여기까지 진행하고 open 된  터미널 창에서 login as에 root를 치고 비밀번호를 입력하면 되는데 비밀번호는 입력해도 표시가 안되기 때문에 당황하지 말고 잘 입력하면 된다.

위와 같이 열리면 로그인 성공!

 

그리고 aws는 계속 100원 결제가 안되서 사용이 불가했던 것이었다. 이 내용을 정리할때 aws도 같이 해볼 것이다.

 


인바운드 규칙

포트 번호를 설정하는 것

aws 기준 > 네트워크 보안 > 보안 그룹

여기서 나오는 서버를 클릭하면 정보를 확인할 수 있고, 세부 사항에서 인바운드 규칙 > 규칙 편집 으로 들어가서 정보를 수정할 수 있다. 

보안 그룹 id를 복사한 후 인스턴스로 넘어가서 보안 그룹 이름과 id도 세부사항에서 확인할 수 있다. 

규칙 추가를 하여 정보를 수정한 후에 검색을 하여 추가하고자하는 id에 추가 할 수 있다.

 

네이버는 

여기서 설정해줄 수 있다.

아파치를 사용하기 위한 과정이다(?)

 

FileZilla

Download FileZilla Client 클릭

기본인 FileZilla 다운로드 후 setup 실행하여 설치한다.

원래 아마존으로 하면

사용자는 ubuntu 키 파일을 불러오면 되는데 네이버 클라우드 플랫폼은 비밀번호 묻기로 하고 사용자는 root로 지정해야한다 포트번호는 putty로 연결할때 사용한 포트를 쓰면 된다.

 

 


웹서버

클라이언트의 http 요청을 받아 다양한 처리를 함

정적 파일을 전달하는 서버를 웹 서버라고 함

아파치 

http 표준을준수하도록구축된오픈소스형식의서버
오래사용되어만큼거의모든OS에서실행이가능하고, 다양한모듈을
갖고있다.

 

아파치 설치

아까 로그인한 터미널에서 

# sudo apt-get update
# sudo apt-get install apache2

를 입력하여 설치한다.

 

그 후에 파일질라에서 var/www/html로 들어가서 index.js를 확인할 수 있고 도메인 주소를 검색하면 

로 시작하는 화면을 확인할 수 있다 

 

그 후에 sudo  chmod 777 /var/www/html // 전송이 가능하도록 해주는 코드

를 터미널에 입력하고 원하는 html파일을 html 폴더로 드래그하여 넣어주면 

도메인/html파일이름 을 입력하면 해당 페이지가 보이는 것을 확인할 수 있다.

 


아파치2 웹서버 루트 디렉토리 변경하는 법

두가지 파일을 수정해서 지정되어 있는 파일을 변경해야한다.

기본값은 /var/www/html로 지정되어 있다 이를 바꾸기 위해

 

sudo nano /etc/apache2/apache2.conf

를 입력하고

연두색 표시되어 있는 줄의 디렉토리 옆을 /root로 바꾸고,

 

sudo nano /etc/apache2/sites-available/000-default.conf

를 입력하고 

DocumentRoot 옆을 /root로 바꾸어 준 후에

 

sudo service apache2 restart

 

를 실행하면 재설정된다. 


IP :

인터넷 상에서 데이터를 주고받기 위한 통신 규약

스마트폰 컴퓨터에 따라 운영체제가 다르고 프로그램마다 구현 언어가 다르기에 이를 네트워크 상에서 통신할 수 있도록 프로토콜이 필요하기 때문에 생김

 

IP 주소 

IP 통신에 필요한 고유 주소

데이터를 주고 받기 위해 사용되는 주소

IPv4 : 32비트 8비트씩 끊어 0-255 사이의 10진수 숫자로 나타냄 / .으로 숫자 구분

IPv6 :  IPv4가 고갈되어 새로 나온 방식 128비트이며, 16진수 숫자 8개로 표기한다 / :으로 숫자 구분

 

끝!! 다음에 정리할 때 좀 더 자세히 정리해야겠다.. 하핳

 

리눅스 명령어 간단 정리

명령어 의미
ls 해당 경로의 폴더에 있는 파일 확인
cd 폴더 이동
vi 파일을 열어서 보여줌
a or i 입력 상태
esc -> : -> wq(수정한 상태를 저장하고 종료) or q!(강제 종료)

 

 

 

 

soket과 http의 차이

soket은 emit을 통해 한번 열어주면 닫지 않을때까지 계속 열려 있다. 그렇기 때문에 실시간 채팅이 가능하다

http는 한번 통신 한 후에 닫기 때문에 실시간으로 채팅을 하기에는 어려움이 있다.

 

씨퀄라이즈와 포스트맨을 통해 만든 테이블에 값 넣고 가져오기

메인 폴더(230810_JOIN)의 index.js

const express = require('express');
const app = express();
const PORT = 8080;
const db = require('./models');

app.set('view engine', 'ejs');
app.use('/views', express.static('./views'));
app.use('/static', express.static('./static'));
app.use(express.json());
app.use(express.urlencoded({extended : true}));


const router = require('./routes/student');
app.use('/', router);

db.sequelize.sync({force: true}).then(() => {//true 값을 넣어야 다시 index.js를 실행할 때 삭제하고 다시만들어준다.
    app.listen(PORT, () => {
        console.log(`http://localhost:${PORT}`);
    });
});

어제와 동일하다

routes 역할의 student.js

const express = require('express');
const router = express.Router();
const controller = require('../controller/Cstudent');

router.get('/', controller.index);
router.post('/student', controller.post_student);
router.post('/class', controller.post_class);
router.get('/student', controller.get_student);

module.exports = router;

controller의 Cstudent.js

const {Student, StudentProfile, Classes} = require('../models')
// 구조 분해 할당으로 값을 넣어줘서 model.~로 안하게함 사실 import를 쓰면 됨

exports.index = (req, res) => {
    res.render('index');
}

//학생 생성
exports.post_student = async (req, res) =>{
   
    try{
        const {userid, password, email, name, major, enroll} = req.body;
        const user = await Student.create({
            userid,
            password,
            email,
            StudentProfile: {
                name,
                major,
                enroll,
            },
        }, {include : StudentProfile}
        );
        console.log(user);
        res.send(user);
    } catch (error) {
        console.log(error);
    }
   

}
exports.post_class = async (req, res) =>{
    try{
        const {name, room, code, teacher_name, StudentId} = req.body
        const classes = await Classes.create({
            name,
            room,
            code,
            teacher_name,
            StudentId,
        })
    } catch(error){

    }
}

exports.get_student = async (req, res) => {
    try {
        const student = await Student.findAll({
            attributes: ['userid', 'email'],
            include: [{model: StudentProfile, attributes: ['major', 'enroll']}]
        });
        res.send(student);
    } catch (error) {
        console.log(err);
    }
}

model 폴더의 Classes.js

const { DataTypes } = require("sequelize");
const { sequelize } = require(".");


const classModel =(sequelize) => {
    const Classes = sequelize.define(
        'Classes',
        {
            id: {
                type: DataTypes.INTEGER,
                allowNull: false,
                primaryKey: true,
                autoIncrement: true,
            },
            name: {
                type: DataTypes.STRING(31),
                allowNull: false,
            },
            room:{
                type: DataTypes.STRING(7),
            },
            code:{
                type: DataTypes.STRING(7),
                allowNull: false,
            },
            teacher_name:{
                type: DataTypes.STRING(15),
            },


        });
        return Classes;
};

module.exports = classModel;

model 폴더의 Student.js

const { DataTypes } = require("sequelize")

const studentModel = (sequelize) => {
    const Stdent = sequelize.define(
        'Student',
        {
            id:{
                type: DataTypes.INTEGER,
                allowNull: false,
                primaryKey: true,
                autoIncrement: true,
            },
            userid: {
                type: DataTypes.STRING(31),
                allowNull: false,
            },
            email : {
                type: DataTypes.STRING(31),

            },
            password : {
                type: DataTypes.STRING(255),
                allowNull: false,
            }
        });
        return Stdent;
}

module.exports = studentModel;

model 폴더의 StudentProfile.js

const { DataTypes } = require("sequelize")

const studentProfileModel = (sequelize) => {
    const StudentProfile = sequelize.define('StudentProfile',{
        id:{
            type: DataTypes.INTEGER,
            allowNull: false,
            primaryKey: true,
            autoIncrement: true,
        },
        name: {
            type: DataTypes.STRING(15),
            allowNull: false,
        },
        major:{
            type: DataTypes.STRING(31),
            allowNull: false,
        },
        enroll: {
            type: DataTypes.INTEGER,
            allowNull: false,
        }
    });
    return StudentProfile
};
module.exports = studentProfileModel;

model 폴더의 index.js

'use strict';

const fs = require('fs');
const path = require('path');
const Sequelize = require('sequelize');
const process = require('process');
const basename = path.basename(__filename);
const env = process.env.NODE_ENV || 'development';
const config = require(__dirname + '/../config/config.json')[env];
const db = {};
const  sequelize = new Sequelize(config.database, config.username, config.password, config);


//모델

db.Student = require('./Students')(sequelize);
db.Classes = require('./Classes')(sequelize);
db.StudentProfile = require('./Studentprofile')(sequelize);

//관계형성
//1:1 학생과 프로필
db.Student.hasOne(db.StudentProfile);
db.StudentProfile.belongsTo(db.Student);

//1:다 학생과 강의
db.Student.hasMany(db.Classes);//, {foreignKey: 'student_id'}외래키 지정을 안하면 알아서 지정을해준다.
db.Classes.belongsTo(db.Student);//, {foreignKey: 'student_id'}

db.sequelize = sequelize;
db.Sequelize = Sequelize;

module.exports = db;

이렇게 하여서 node index.js를 실행시키면 지정한 데이터베이스에 테이블이 들어간다 그 후에 포스트맨에서 워크 스패이스를 만든 후 값들을 넣을 수 있다.

 

※ 여기서 model폴더의 index.js에서 외래키를 지정하던 문자을 빼서 씨퀄라이즈에서 자동으로 외래키를 만들어주는데 만들어줄때는 define으로 정의된 이름에 id를 CamelCase 형식으로 붙여서 외래키 이름을 만들어준다. 위의 코드를 실행한후 Classes와 StudentProfile에 생성된 외래키를 보면 다음과 같다

※ autoincrement는 id를 자동으로 갱신시켜준다.

 

포스트맨으로 값 넣고 가져오기

라우트에 있는 주소를 입력한 후 req.body로 받기 때문에 Body > raw > JSON으로 바꾸고 객체로 데이터를 보낼 수 있다. 이렇게 한 다음 send를 누르면 컨트롤러 폴더 Cstudent.js의 학생 생성 함수(?)가 돌아가고 값을 넣은 후에 다시 돌려보내준다.

classes 테이블에도 같은 방식으로 값을 넣는다.

그리고 원하는 데이터를 가져오기 위해 get을 이용한다

위와 같이 get으로 send를 해주면 라우터가 아래의 코드와 연결 시켜준 후에 원하는 이름을 입력하여 원하는 데이터를 받을 수 있다.

exports.get_student = async (req, res) => {
    try {
        const student = await Student.findAll({
            attributes: ['userid', 'email'],
            include: [{model: StudentProfile, attributes: ['major', 'enroll']}]
        });
        res.send(student);
    } catch (error) {
        console.log(err);
    }
}

 


Cookie와 Session

Cookie

웹브라우저에 저장되고 키와 값이 들어있는 작은 데이터 파일

[동작 방식]

1. 클라이언트가 페이지를 요청

2. 서버에서 쿠키를 생성

3.http 헤더에 쿠키를 포함하여 응답

4. 브라우저가 종료되어도 쿠키 만효 기간이 지나지 않았다면 클라이언트에서 보관하고 있다.

5. 같은 요청을 할 경우 http 헤더에 쿠키를 함께 보냄

6. 서버에서 쿠키를 읽어 이전 상태 정보를 변경할 필요가 있을때, 쿠키를 업데이트하고 http 헤더에 포함시켜 응답

위와 같은 방법으로 확인 가능

 

Cookie 사용하기

npm i cookie-parser 명령어로 설치한 후에

 

const cookieParser = require("cookie-parser");

app.use(cookieParser());

 

res.cookie('쿠키 이름', '쿠키값', '옵션 객체')

 

위의 방법으로 사용 가능하다.

 

npm init -y

npm i express ejs cookie-parser

 

import express from 'express';
import cookieParser from 'cookie-parser';
const app = express();
const PORT = 8080;

app.set('view engine', 'ejs');
app.use('/views', express.static('./views'));
app.use('/static', express.static('./static'));
app.use(express.json());
app.use(express.urlencoded({extended : true}));

//쿠키 파서
// app.use(cookieParser());

//암호화
app.use(cookieParser('12341234'));

//쿠키 옵션
const cookieConfig = {
    // httpOnly : 웹 서버를 통해서만 쿠키에 접근할 수 있다.
    // 자바스크립트에서 document.cookie를 이용해서 쿠키에 접속하는 것을 차단한다.
    // maxAge : 쿠키 수명 밀리초
    // expires : 만료 날짜를 GMT시간 설정
    // path: 해당 디렉토리와 하위 디렉토리에서만 경로가 활성화 되고 웹 브라우저는 해당하는 쿠키만 웹 서버에 전송된다
    // 쿠키가 전송될 url을 특정할 수 있다 (기본값 : '/')
    // domain : 쿠키가 전송될 도메인을 특정 가능 ( 기본 값 : 현재 도메인)
    // secure : 웹 브라우저과 웹 서버가 https로 통신하는 경우만 서버에 전송
    // signed : 쿠키의 암호화 결정 ( req.signedCookies 객체에 들어있다.)
    httpOnly: true,
    maxAge: 60 * 1000,//1분
    signed : true
}

app.get('/', (req, res) => {
    res.render("index");
});
 
app.listen(PORT, () => {
    console.log(`http://localhost:${PORT}`);
});

ejs ▽

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <a href="/setCookie">쿠키 설정</a>
    <a href="/checkCookie">쿠키 확인</a>
    <a href="/delCookie">쿠키 제거</a>
</body>
</html>
app.get('/setCookie', (req, res) => {
    //쿠키이름 쿠키 값 옵션
    res.cookie('myCookie', 'myVal', cookieConfig);
    res.send('set cookie');
})

app.get('/checkCookie', (req, res) => {
    //쿠키이름 쿠키 값 옵션
    // res.cookie('myCookie', 'myVal', cookieConfig);
    res.send(req.signedCookies);
})

app.get('/delCookie', (req, res) => {
    res.clearCookie('myCookie', 'myVal', cookieConfig);
    res.send('clear cookie')
})

위 코드를 맨위의 코드 get과 listen 사이에 넣어서 사용

 

Session

웹 서버에 저장되는 쿠키 웹 브라우저를 통해 접속한 시점부터 연결을 끝내는 시점까지의 시간 동안 일련의 요구를 하나의 상태로 보고 그 상태를 유지 시킨다.

[동작 방식]

1. 클라이언트가 서버에 접속 시 세션 id를 발급 받음

2. 클라이언트는 세션 id에 대해 쿠키를 사용해서 저장하고 가지고 있다

3. 클라이언트는 서버에 요청할 때, 이 쿠키의 세션 id를 서버에 전달해서 사용합니다.

4. 서버는 세션 id를 전달받아서 별다른 작업 없이 세션 id로 세션에 있는 클라이언트 정보를 가져옴

5. 클라이언트 정보를 가지고 서버 요청을 처리여 클라이언트에게 응답

 

npm i express-session를 입력하여 설치 후 사용

 

 

join을 배워보자

 

데이터베이스의 조인은 두 개 이상의 테이블에서 데이터를 결합하여 새로운 결과를 생성

테이블 간의 관계를 통해 의미 있는 정보를 얻어내야 할 때 조인을 사용하 여 관련된 데이터를 결합하고 원하는 정보를 추출

 

조인의 종류

• INNER JOIN: 공통된 값만을 가진 행 반환.

• LEFT JOIN: 왼쪽 테이블 모든 행 포함하며, 오른쪽 테이블과 일치하는 경우 함께 반환.

• RIGHT JOIN: 오른쪽 테이블 모든 행 포함하며, 왼쪽 테이블과 일치하는 경우 함 께 반환.

• FULL JOIN: 양쪽 테이블 모든 행을 포함하며, 일치하는 경우 함께 반환.

• CROSS JOIN: 두 테이블 모든 가능한 조합 반환.

 

조인 명령어

selet 조회할 필드 from 테이블명 inner join 조인할 테이블명 on 일치해야할 필드

ex)

 orders 테이블의 고객아이디와 customers 테이블의 고객아이디가 같은 필드를 order테이블과 customers테이블에서 찾아서 orders 테이블의 아이디와 customers 테이블의 고객 이름을 출력해서 보여준다

 

Relationship (관계 설정)

 ▶ 1:1

 ▶ 1:다

 ▶다:다

관계를 형성해야 무결성 오류가 나지 않는다.

1:1

각 테이블은 서로 한가지 정보를 공유하며 관계되어 있다

ex) 사용자와 프로필, 주문과 송장

MYSQL

id를 공유한다

씨퀄라이즈

- hasOne: 한 모델이 다른 모델을 가리키는 1:1 관계를 설정하는 데 사용

- belongsTo: 다른 모델이 한 모델을 가리키는 1:1(1:다) 관계를 설정하는 데 사용

 

 

1:다 관계

한 쪽 레코드(행)가 다른 쪽 레코드(행)의 여러개와 관련되어 있다.

ex) 부서와 직원, 학교와 학생

MYSQL

씨퀄라이저

다수를 hasMany로 먼저 선언한다.

hasMany: 한 개의 모델(테이블)이 다른 모델과 1:n 관계를 가질 때 사용

belongsTo: 다른 모델이 한 모델을 가리키는 1:1(1:다) 관계를 설정하는 데 사용

 

다:다

실무에서 많이 사용하지는 않는다. 

하나의 레코드가 다른 하나의 레코드와 관련되어 있는 관계를 의미합니다. 이 관계에서 각 레코드는 서로 한 가지 정보만을 공유합니다.

ex) 학생과 과목, 주문과 제품, 배우와 영화

MYSQL

씨퀄라이저

belongsToMany: 다:다 관계를 설정할 때 사용되는 메서드

 

sequelize로 데이터베이스 만드는 법

1. 폴더 생성

2. npm init -y

3. npm i express mysql2 sequelize sequelize-cli(모듈 다운로드)

4. npx sequelize init(씨퀄라이즈 실행)

5. config 제이슨 파일에서 데이터베이스 연결하기

development에서 유저이름과 패스워드 데이터베이스 지정하여 입력하기

(유저 등록법)

위의 명령어를 입력하여 유저를 등록할 수 있다.

유저이름 : user

비밀번호: 1234

select * from mysql.user; // 등록 확인을 할 수 있다.

유저의 plugin에 이렇게 표기되어 있어야한다.

6. models의 index.js에서 fs 지우고,

if 어쩌고의 else문을 const로 선언해준다.

7. 데이터 베이스 만들기

models 폴더에서 만들어줘야한다.

학생

const studentModel = (sequelize) => {
    const Stdent = sequelize.define(
        'student',
        {
            id:{
                type: DataTypes.INTEGER,
                allowNull: false,
                primaryKey: true,
                autoIncreament: true,
            },
            name: {
                type: DataTypes.STRING(15),
                allowNull: false,
            },
            major:{
                type: DataTypes.STRING(31),
                allowNull: false,
            },
            enroll: {
                type: DataTypes.INTEGER,
                allowNull: false,
            }
        });
        return Stdent;
}

module.exports = studentModel;

수업

const classModel =(sequelize) => {
    const Classes = sequelize.define(
        'classes',
        {
            id: {
                type: DataTypes.INTEGER,
                allowNull: false,
                primaryKey: true,
                autoIncreament: true,
            },
            name: {
                type: DataTypes.STRING(31),
                allowNull: false,
            },
            room:{
                type: DataTypes.STRING(7),
            },
            code:{
                type: DataTypes.STRING(7),
                allowNull: false,
            },
            reacher_name:{
                type: DataTypes.STRING(15),
            },


        });
        return Classes;
};

module.exports = classModel;

을 통해 데이터베이스를 만들 수 있다.

8. 서버를 열어줘야지 적용할 수있다.

메인 폴더의 index.js

const express = require('express');
const app = express();
const PORT = 8080;
const db = require('./models');

app.set('view engine', 'ejs');
app.use('/views', express.static('./views'));
app.use('/static', express.static('./static'));
app.use(express.json());
app.use(express.urlencoded({extended : true}));


const router = require('./routes/student');
app.use('/', router);

db.sequelize.sync({force: false}).then(() => {
    app.listen(PORT, () => {
        console.log(`http://localhost:${PORT}`);
    });
});

routes 폴더의 student.js

const express = require('express');
const router = express.Router();
const controller = require('../controller/Cstudent');

router.get('/', controller.index);

module.exports = router;

controller 폴더의 Cstudent.js

exports.index = (req, res) => {
    res.render('index');
}

models 폴더의 index.js

'use strict';

const fs = require('fs');
const path = require('path');
const Sequelize = require('sequelize');
const process = require('process');
const basename = path.basename(__filename);
const env = process.env.NODE_ENV || 'development';
const config = require(__dirname + '/../config/config.json')[env];
const db = {};
const  sequelize = new Sequelize(config.database, config.username, config.password, config);


//모델

db.Student = require('./Students')(sequelize)
db.Classes = require('./Classes')(sequelize)

//관계형성
db.Student.hasMany(db.Classes, {foreignKey: 'student_id'});
db.Classes.belongsTo(db.Student, {foreignKey: 'student_id'});

db.sequelize = sequelize;
db.Sequelize = Sequelize;

module.exports = db;

이렇게 만든 후에 node index.js를 실행시켜주면 테이블이 만들어지는 것을 확인할 수 있다.

 

이는 1:다 관계이다.

한명의 학생이 여러개의 수업을 들을 수 있다.

 

※ 메인 폴더의 index.js

db.sequelize.sync({force: true}).then(() => {//true 값을 넣어야 다시 index.js를 실행할 때 삭제하고 다시만들어준다.
    app.listen(PORT, () => {
        console.log(`http://localhost:${PORT}`);
    });
});

왜래키 지정을 잘못해서 다시 실행시키려고 할때 위와 같이 true값을 넣어줘야 삭제하고 다시 만들어준다.

 

1:다 관계로 테이블을 만들었으니 join을 해보자

as를 사용해서 더 간편하게 사용하는 것도 가능하다

그리고 as를 통해 테이블 헤드의 이름도 바꿀 수 있다

+ Recent posts