이제 node에서 DB와 연결을 해야지
그럴려면 또 설치해야할 라이브러리가 있다.
Object Relational Mapping
으로 분류가 되는 이녀석은
JS 객체와 DB의 릴레이션을 맵핑해주는 도구다.
타 DBMS들과도 연결이 되기때문에
(MariaDB, PostgreSQL, SQLlite, MSSQL 등등..)
문법 면에서 조금 차이가 있더라도 호환이 되므로
타 SQL로 전환 시에도 문제 없이 쓸 수 있다
이걸 쓰는 이유는?
SQL 언어를 직접 안써도 JS 만으로 충분히 DB 조작이 가능하며
SQL문을 잘 몰라도 어느정도는(?) 다룰 수 있음.
기본 셋팅 부터 좀 하고..
npm init
필요한 패키지들 설치도 하고..
npm i express morgan nunjucks sequelize sequelize-cli mysql2
npm i -D nodemon
처음 보는게 있군.
- sequelize-cli : 시퀄라이즈 명령어 실행을 위한 패키지.
- mysql2 : MySQL과 시퀄라이즈 연결해줄 드라이버. (mysql2 이거 자체가 DB 프로그램아님 주의!)
전역 설치 없이 명령어로 쓰려 npx를 붙였다
sequelize init
없던게 생겼다
config, models, migrations, seeders 폴더가 생겨났다
그리고 models안에 index.js가 있는데
sequelize-cli가 자동 생성해주는 코드를 고대로 쓸때마다
뭔 에러가 뜨나보며, 필요 없는부분들도 있어
좀 수정을 해줘야 한단다
근데 이게 맞아..?
![]() |
![]() |
Sequelize는 시퀄라이즈 패키지이자 생성자임
config 폴더 안에 config.json에서 DB 설정을 불러와
new Sequelize 통해 MySQL 연결 객체를 생성
그리고 그 연결 객체 나중에 쓰기위해 db.sequelize에 넣어
MySQL 연결하기
app.js 만들어 express와 sequelize를 연결 해줄 코드를 작성 한다.
이 빈곳에.. 무 에서 유를 만드는건데
이게 한에 잘 될까...
기록을 잘 해서 보고 하는게 좋을까...
개발자로써 가끔 현타오는점이다
아니 내가 개발자는 맞나 싶음...
app.js | |
![]() |
require('./module') 은 require('./module/index.js')와 같음 db.sequelize를 불러와 sync메서드를 사용해 서버 실행시 MySQL과 연동되게 함 (force옵션을 false로 했는데 이걸 true로 하면 서버 실행때 마다 테이블을 새로 만든다. 테이블 잘못 만든 경우에 true로 하면됨) |
![]() |
|
![]() |
MySQL 연동시 config 폴더 안 config.json 정보가 쓰임 때문에 지금 DB에 맞게 수정 해줘야 한다 password와 database 정도만 고치면 됨. |
confing.json의 development에 한 설정은 여기 보면...
process.env.NODE_ENV 가 development일때 적용된다.
(development은 기본 설정임..)
배포 환경에서 DB 설정 할때는 저기 3번째의 production 속성 부분을
고치면됨.
[ test 환경(process.env.NODE_ENV 가 test 일때) 2번째 test를 수정 ]
서버 실행. .
3001 포트 대기중이며
Database 연결도 성공!
Models
Mysql에 정의해노 테이블을
Sequelize에서도 정의 해줘야된다
Sequelize는 model과 MySQL의 테이블을 연결해 준다
User와 Commenter 모델을 만들어서
users 테이블과 commenter 테이블을 연결해 볼거다
User 모델 만들기
users 테이블과 연결 | |
![]() |
▶ User 모델을 만들어 module로 exports ▶ User 모델은 Sequelize.Model을 확장한 class로 선언 모델은 static init 메서드와 static associate 메서드로 나뉜다 ▶ static init : 테이블에관한 설정 - super.init : 첫번째 인수 = 테이블 컬럼에 대한 설정 두번째 인수 = 테이블 자체에 대한 설정 - id 컬럼은 sequelize에서 알아서 기본키로 연결함. 대신 나머지 컬럼들의 스펙만 작성하면 됨. (MySQL 테이블 내용과 일치하게 적어야함) ▶ static associate : 다른 모델과의 관계 |
Sequelize는 MySQL과 자료형의 명칭이 조금 다르다.
Sequelize | MySQL |
STRING(100) | VACHAR(100) |
INTEGER | INT |
BOOLEAN | TINYINT |
DATE | DATETIME |
INTEGER.UNSIGNED | INT UNSIGNED |
allowNull: false | NOT NULL |
unique: true | UNIQUE |
defaultValue: Sequelize.NOW | DEFAULT now() |
super.init의 두번째 인수는 테이블의 옵션을 설정한다
- sequelize : static init 메서드의 매개변수와 연결되는 옵션. db.sequelize 객체를 넣어야함. (model/index.js에서 연결 할거)
- timestamps : 자동으로 날짜 컬럼을 추가하는 기능. 이걸 true로 두면 활성화 되며 seauelize는 자동으로 createdAt와 updatedAt 컬럼을 생성해 row열 생성시 시간과 날짜를 자도으로 입력함. 그럼 false로 설정한 이유는 created_at에서 이미 기능구현을 했기 때문에 중복될 필요는 없어 뺐음.
- underscored : sequelize는 기본으로 테이블명과 컬럼명을 camel case로 만든다. 이걸 snake case로 바꾸는 옵션. (기본으로 지들이 설정해둔 명칭을 쓰는데 그걸 해제하고 내가 db에 설정한 명칭대로 한다는 말임.)
- modelName : 모델명 설정 가능. node 프로젝트에서 사용.
- tableName : 실 Database의 Table 명칭. ( 기본적으로 모델명은 소문자, 복수형 으로 만드는편임.)
- paranoid : true일때 deleteAt이라는 컬럼이 생기는데 여긴 row를 지웠을때 완전지워지지 않고 그 지워진 시간이 기록된다. 조회를 했을시엔 deleteAt의 null인(삭제안됬음)을 보게됨. 나중에 다시 살리기 위해서 그렇다.( 지웠던 row열 다시 되살리고 싶다면 true로 해놓자)
- charset과 collate : 한글입력을 위해 하는 설정. ( 이모티콘까지 입력 하고 싶다면 : utf8mb4 / utf8mb4_general_ci 입력.
Commenter 모델 만들기
commets 테이블과 연결 | |
![]() |
왜 users 테이블과 연결되는 commenter 컬럼이 없..지? (모델 정의할 때 넣어도 되나 Sequelize 자체에서 관계를 따로 정의해줘도됨.) |
models/index.js와 연결(등록)하기
![]() |
▶ db 객체 안에 Users와 Comments 모델을 담아뒀음. (db 객체를 require 해서 내가 생성한 모델에 접근이 가능) ▶ Users.init과 Comments.init은 각 모델의 static.init 메서드를 호출하는것 (이 init이 실행되야 테이블이 모델로 연결이 된다.) ▶ 다른 테이블과의 관계를 연결하는 associate 메서드도 실행 시켜둔다. |
이제 users와 comments의 관계를 설정해보자
관계 정의
와 이거 정처기 필기 공부하며 본건데. . ㅋㅋ
저 두 테이블간 관계를 정의 해야 한다.
유저(users) 한명에 댓글(comments)을 여러번 쓸수 있지?
그럼 1:N 관계겠네?
1:1 의 관계 같은 경우는 유저와 유저정보 테이블간 관게
N:M의 관계 같은 경우는 지금 블로그 같이럼 게시글과 해쉬태그간 관계겠고..
MySQL에선 JOIN 기능으로 여러 테이블간의 관계를 파악해 결과를 도출 할 수 있다.
Sequelize에선 이 JOIN 기능도 알아서 구현해 준다.
뭐 어떤 테이블간 뭔 관계인지만 알려주면 된다.
1:N
models/user | models/comment |
![]() |
![]() |
▶ hasmany : | ▶ belongsTo : 다른 모델의 정보가 들어가는 테이블에 쓰임. ▶ commenter 컬럼이 추가되는 Comment 모델에 쓰면됨. ▶ 사용자 한명에 그에 속한 글은 여러개므로 댓글 row에 누가쓴건지(commenter)를 알아야 하니까 ▶ Sequelize는 정의 한대로 모델간 관계를 파악해 Comment 모델에 FK(외래키)인 commenter 컬럼을 추가. Commenter 모델의 FK 컬럼은 commenter고 User 모델의 id컬럼을 가리키고있음. |
hasmany 에서 sourckey에 id를 넣고 belongsTo 에서 targetKey에 id를 넣었다 저 두 id는 모두 User 모델의 id를 말한다 foreignKey를 지정하지 않았다면, 모델명+기본키 인 컬럼이 모델에 자동생성될거다 (commenter를 FK로 직접 지정 안하면 user(모델명) + 기본키(id)가 합쳐진 UserId가 FK로 자동 생성된다 |
이 부분 알것 같으면서 뭔가 잘 그림이 안그려짐. .
이해만 가면 만들기 어렵지 않을거 같은디..
이대로 돌렸는데 에러가 났다. .
https://whaledowny.tistory.com/47
node 서버를 돌렸는데 type Error가 떳을때
이젠 뭐 당황스럽지도 않다.. 나중에 또 같은 오류가 떳을시 시간 절약을 위해 기록하는것.. 이번에 내가 한건 모델만 정의 해줬다. 그럼 생각해 보자. - 오타가 있었을수 있음. - 자동완성이지만
whaledowny.tistory.com
1시간 걸려 고쳤는데.. 소 뒷걸음치다 고친격이라
모르겠다... 누가 설명좀 해줬음 좋겠네 ㅜㅜ
1:1
이땐 hasmany가 아닌 hasOne 메서드를 쓰면된다
models/user | models/Info |
![]() |
![]() |
1:1 이라도
hasOne과 belongsTo가 반대가 되면 안됨!
belongsTo를 사용하는 Info 모델에 UserId 컬럼이 추가되기 때문!
N:M
이런 관계를 표현 하기 위해 belongsToMany 메서드가 있다
게시글을 담고있는 Post 모델과
해쉬태그 정보가 담긴 Hashtag 모델이 있다고 하자
models/post | models/hashtag |
db.Post.belongsToMany(db.Hashtag, { through: 'PostHashtag' }); | db.Hashtag.belongsToMany(db.Post, { through: 'PostHashtag' }); |
양쪽 다 belongsToMany 를 쓰고
N:M 특성상 새로운 모델이 생성된다
through 속성에 그 이름을 쓰면 된다.
그럼 새로 생성된 PostHashtag 모델에
게시글과 해쉬태그의 아이디값이 저장된다.
Post | PostHashtag | Hashtag | |||
id | content | postid | hashtagid | id | title |
1 | #node #express | 1 | 1 | 1 | node |
2 | #node bester | 1 | 2 | 2 | express |
3 | #JavaScript | 2 | 1 | 3 | JavaScript |
3 | 3 |
N:M은 조회시 여러 단계를 거친다
#node를 사용한 게시글을 조회 한다 해보자
#node를 먼저 Hashtag 모델에서 조회,
갖고온 태그 id값을 가지고 PostHashtag 모델에서 hashtagid가 1인 postid를 찾은 다음
postid 값을 갖고 Post 모델에서 그 정보를 갖고 온다.
자동으로 만들어진 모델일 경우는 다음처럼 접근이 가능함
'Back-End Frameworks > Node.js' 카테고리의 다른 글
16)Nodejs_MySQL(5)_쿼리 수행 (본게임 시작.)_기본형태. .? (0) | 2023.07.23 |
---|---|
15)Nodejs_MySQL(4)_Sequelize로 CRUD, 관계 쿼리 (0) | 2023.07.21 |
13)Nodejs_MySQL(2)_DB, 테이블 생성, CRUD (0) | 2023.07.20 |
12)Nodejs_ MySQL(1)_SQL언어를 쓰는 관계형 DBMS (0) | 2023.07.19 |
11)Nodejs_ Express Web Server_(2) Router, req res ,Template Engine(일단 보류. .ㅎㅎ) (0) | 2023.07.18 |