node.js

[Node] Node.js + mySQL + Sequelize로 데이터베이스 테이블 만들어보자

JJIMJJIM 2024. 5. 1. 01:30
728x90
반응형
SMALL

 

 

[Node] Node.js + mySQL + Sequelize로 데이터베이스 테이블 만들어보자

강의에서 백엔드 구성을 위 세가지를 사용하는 것을 보았다.

앞으로는 프론트도 백단을 알고있어야 한다고 생각하는 것과 함께

다음에 내가 프로젝트를 혼자 만들때 이걸보고 참고해서 만들기 위해서

이번에 잘 알아두고자 블로그에 올린다.

 

Node.js?

  • Node.js는 JavaScript를 서버 측에서 실행할 수 있게 해주는 런타임 환경입니다.
  • 원래 JavaScript는 브라우저 내에서만 실행되었지만, Node.js 덕분에 개발자들은 웹 서버 개발에도 JavaScript를 사용할 수 있게 되었습니다.
  • node가 서버가 아니냐고 착각하는 분들이 있는데 node에서 제공하는 http모듈이 서버 입니다. 
  • Express.js
    • Node.js의 웹 애플리케이션 프레임워크
    • 웹 서버를 빠르고 쉽게 구축할 수 있도록 설계되었으며, 다양한 라우팅 기능과 미들웨어 옵션을 제공하여 확장성 있는 API를 개발할 수 있게 해줍니다.
    • 기본 node의 http모듈 보다 깔끔하고 구조적으로 짤 수 있다.
    • 내부적으로 http를 사용해서 서버를 돌릴 수 있다.

필요한 모듈

npm i express

 

 

mySQL?

  • MySQL은 관계형 데이터베이스 관리 시스템(RDBMS)으로, 구조화된 데이터를 효율적으로 저장하고 관리할 수 있습니다.
  • SQL(Structured Query Language)을 사용하여 데이터를 쿼리합니다.

필요한 모듈

mySQL 설치가 처음이라면  아래 링크 참고하세요 (제로초의 node.js 교과서)

https://thebook.io/080334/0319/

mysql installer for window 다운로드 및 설치

mySql workbench 설치 => 데이터베이스를 들여다 보려면 터미널에서 명령어 쳐서 해야하는데,
시각화해서 편하게 만들어준것

 

 

 

 

Sequelize?

  • Sequelize는 Node.js 환경에서 사용할 수 있는 Promise 기반 ORM(Object-Relational Mapping) 라이브러리입니다.
  • 데이터베이스의 테이블을 JavaScript 객체로 매핑함으로써 SQL 쿼리를 직접 작성하지 않고도 데이터베이스를 조작할 수 있게 해줍니다.
  • 즉, SQL언어를 사용하는 mySQL를 자바스크립트로 조작할 수 있게 해주는 라이브러리

필요한 모듈

npm i sequelize sequelize-cli mysql2

mysql2 = 노드와 mysql을 연결해주는 드라이버

 

 

 

 

초기 세팅 해보자

sequelize 초기 세팅

npx sequelize init

--> config, migrations, models, seeders의 폴더가 생긴다.
--> /config/config.json 파일에 들어가 data-base명과 password를 입력한다.
--> host는 기본 127.0.0.1
--> portsms 3306

 

 

mySQL과 sequelize 연결하기

/models/index.js

/models/index.js

const Sequelize = require("sequelize");
 // 운영버전일땐 production 개발할땐 development
const env = process.env.NODE_ENV || "development";
// config데이터를 가져온거에서 development의 데이터 가져옴
const config = require("../config/config")[env];
const db = {};

// sequelize가 node와 mySQL연결해는 코드
// sequelize는 내부적으로 mySQL툴 사용.
// node와 mySQL을 연결해주는 드라이버역할인 mysql2라이브러리에 필요정보를 줘서 역할을 수행하게 함
// 연결성공하면 sequelize객체에 연결정보가 담김
// 근데 연결만 성공해서는 아무 의미 없고 mySQL에 테이블들을 만들어줘야한다.
const sequelize = new Sequelize(config.database, config.username, config.password, config);

Object.keys(db).forEach((modelName) => {
	if (db[modelName].associate) {
		db[modelName].associate(db);
	}
});

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

module.exports = db;

 

 

sequelize 모델 만들기

/models/user.js

/models/user.js

module.exports = (sequelize, DataTypes) => {
    const User = sequelize.define(
        // define한 User은 모델의 이름.
        // mySQL에는 자동으로 소문자, 복수가 되어서 users 테이블로 저장됨.
        // 첫번째 객체 : user 정보
        // 두번째 객체 : user모델에 대한 세팅
        "User",
        {
        	// id: {}, // id는 mySQL에서 자동으로 넣어주기 때문에 여기서 만들 필요 없다.
            // 각 컬럼들에 대한 정의
            email: {
            	// datatypes = STRING, TEXT, BOOLEAN, INT, INTEGER, FLOAT, DATETIME
                type: DataTypes.STRING(30), // 최대 30자까지의 문자열
                allowNull: false, // NULL 값을 허용하지 않음 (필수 값)
                unique: true, // 고유한 값, 중복 불가
            },
            nickname: {
                type: DataTypes.STRING(30), // 최대 30자까지의 문자열
                allowNull: false, // NULL 값을 허용하지 않음
            },
            password: {
                type: DataTypes.STRING(100), // 비밀번호는 암호화할 때 길이가 길어지므로 100자 제한
                allowNull: false, // NULL 값을 허용하지 않음
            },
        },
        {
            charset: "utf8", // UTF-8 인코딩
            collate: "utf8_general_ci" // 일반적인 비교 방식을 사용 // 한글 저장
        }
    );

    // 테이블간의 관계 설정
    // 테이블간의 관계에서는 associate 사용 (글과 글을 쓴사람, 팔로워와 팔로잉 등등 여러테이블이 관계 되어있을때)
	// 그래서 mySQL같은걸 관계형 데이터베이스라고도 한다.
    User.associate = (db) => {
        // User와 Post는 1:N 관계(1대다)
        // User.hasMany(db.Post) = 유저는 포스트를 많이 가질 수 있다.
         // 유저가 쓴 Post들의 정보를 유저에 쓰지 않는 이유는
         // 한칸에 하나의 데이터만 들어가야하는데 많아지면 그럴수 없기 때문이다. (, or 여러정보 안된다)
         // 그래서 hasMany가 있는곳에 많이 가지고 있을 데이터를 갖고있는건 원칙적으로 맞지 않다.
         // hasMany당한 즉 belongsTo를 사용하는 컬럼에서 갖고있어야 한다.
        db.User.hasMany(db.Post);
        db.User.hasMany(db.Comment);
        
        // User와 Post는 N:M 관계(다대다), "Like"라는 중간 테이블을 통해 연결
        db.User.belongsToMany(db.Post, { through: "Like", as: "Liked" });
        
        // User와 User는 N:M 관계, "Follow"라는 중간 테이블을 통해 팔로워와 팔로잉 관계 설정
        // User의 Followers 찾기
        db.User.belongsToMany(db.User, { through: "Follow", as: "Followers", foreignKey: "FollowingId" });
        // User의 Followings 찾기
        db.User.belongsToMany(db.User, { through: "Follow", as: "Followings", foreignKey: "FollowerId" });
        
        // 예: post 모델에서 사용
        db.Post.belongsTo(db.Post, { as: "Retweet" }); // 리트윗 할때 post끼리 관계
    };

    return User;
};

 

추가 설명

sequelize.define 함수의 두번째 객체는 user모델에 대한 세팅이 들어간다.

거기에서 coollate 키값을 가진 데이터는

  • collate: "utf8_general_ci",  // 한글 저장
  • collate: "utf8mb4_general_ci"  // 한글 + 이모티콘 저장

 

 

sequelize 모델 결합 (index.js에 모델들 등록)

/models/index.js

/models/index.js

const Sequelize = require("sequelize");
const env = process.env.NODE_ENV || "development";
const config = require("../config/config")[env];
const db = {};

// sequelize가 node와 mySQL연결해는 코드
// node와 mySQL을 연결해주는 드라이버역할인 mySQL2라이브러리에 필요정보를 줘서 역할을 수행하게 함
const sequelize = new Sequelize(config.database, config.username, config.password, config);

// 빈 객체 db에 모델 5개 등록
// comment.js에서 module.exports로 가져온 함수 실행 -> 모델이 sequelize에 등록
db.Comment = require("./comment")(sequelize, Sequelize);
db.Hashtag = require("./hashtag")(sequelize, Sequelize);
db.Image = require("./image")(sequelize, Sequelize);
db.Post = require("./post")(sequelize, Sequelize);
db.User = require("./user")(sequelize, Sequelize);

// 모델이 채워진 db객체를 반복문 돌려서 associate 실행
Object.keys(db).forEach((modelName) => {
	if (db[modelName].associate) {
		db[modelName].associate(db);
	}
});

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

module.exports = db;

 

 

app.js에 모델 불러오기 / sequeliz sync 맞추기

// node에서는 import / export 안쓰고 require / module.exports 사용
const express = require("express");
const postRouter = require("./routes/post");

// sequelize에서 model 모두 등록
// express에서 그 sequelize를 등록해야 한다.
const db = require("./models");
const app = express();
db.sequelize
	.sync()
	.then(() => {
		console.log("db연결 성공!");
	})
	.catch(console.error);

app.listen(3065, () => {
	console.log("서버 실행 중");
});

 

 

 

명령어로 실행

models를 sequelize에 등록, sequelize를 express에 등록 후

npx sequelize db:create --> sequelize 초기 생성

node app --> 실행

 

 

그런데 이러한 경우엔 코드를 바꿀때마다 껐다가 다시 켜줘야하는 불편함이 있다.

이럴때는 

// 노드에서 코딩을하고나서 매번 껐다 켰다 해야 확인할 수 있는데, 이를 자동화해주는 라이브러리
npm i -D nodemon

/package.json 에 등록
"scripts": {
    "dev": "nodemon app"
},

npm run dev로 실행

 

이러면 코드가 바뀔때마다 자동으로 재실행된다.

 

 

 

결과

mySQL에 config.js에 database명으로 지정해놓은

react-nodebird라는 이름으로 데이터베이트 칼럼이 들어있는것을 확인할 수 있다.

뿐만아니라 model을 만들고 그걸 sequelize에 등록 -> sequelize를 express에 등록한 것들도

모두 확인 할 수 있다.

 

 

 

 

 

 

 

참조!

https://www.inflearn.com/course/lecture?courseSlug=%EB%85%B8%EB%93%9C%EB%B2%84%EB%93%9C-%EB%A6%AC%EC%95%A1%ED%8A%B8-%EB%A6%AC%EB%89%B4%EC%96%BC&unitId=48832&category=questionDetail&tab=curriculum

 

학습 페이지

 

www.inflearn.com

 

728x90
반응형
LIST