Node.js 교과서 7장을 공부하고

⚠️ 본 포스팅은 매주 Node.js를 공부하고, 동아리 스터디원들과 함께 스터디한 내용을 정리하는 곳입니다.

⚠️ 모든 내용을 기록하려고 하기 보다는 함축하고 필요한 내용만 작성하고 있습니다.

https://github.com/gilbutITbook/080229

7.6 sequelize를 통하여 CRUD 작업하기

sequalize.js는 node.js 에서 MySQL 작업을 쉽게 할 수 있도록 도와주는 ORM 라이브러리

MySQL이외에도 MariaDB, PostgreSQL, SQLite, MSSQL 등 다른 데이터베이스도 사용가능

새 프로젝트 생성 후 sequelize 설치

npx express learn-sequelize --view=pug
cd learn-sequelize
npm install
npm install sequelize mysql2

npm install -g sequelize-cli
sequelize init

models/index.js

const path = require('path');
const Sequelize = require('sequelize');

const env = process.env.NODE_ENV || 'development';
const config = require(path.join(__dirname, '..', 'config', 'config.json'))[env];
const db = {};

const sequelize = new Sequelize(config.database, config.username, config.password, config);

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

module.exports = db;

MySQL 연결하기

app.js

...
const sequelize = require('./models).sequelize;

sequelize.sync();
...

sync 메서드 사용하면 start시에 MySQL과 연결됨

모델 정의하기

models/user.js

module.exports = (sequelize, DataTypes) => {
	return sequelize.define('user', {
    	name: {
        	type: DataTypes.STRING(20),
            allowNull: false,
            unique: true,
        },
        age: {
        	type: DataTypes.INTEGER.UNSIGNED,
            allowNull: false,
        },
        married: {
        	type: DataTypes.BOOLEAN,
            allowNull: false,
        },
        comment: {
        	type: DataTypes.TEXT,
            allowNull: true,
        },
        created_at: {
        	type: DataTypes.DATE,
            allowNull: false,
            defaultValue: sequelize.literal('now()'),
        },
    }, {
    	timestamps: false,
    });
};
  • sequelize.js 는 id 를 기본 키로 연결해 주므로 컬럼 추가 불필요

  • VARCHAR는 STRING

  • INT는 INTEGER

  • TINYINT는 BOOLEAN

  • DATETIME은 DATE

  • INTEGER.UNSIGNED는 UNSIGNED 옵션이 적용된 INT

  • allowNull은 NOT NULL

  • timestamps 속성이 true일시 createdAt, updatedAt 컬럼 자동 추가

models/comment.js

module.exports = (sequelize, DataTypes) => {
	return sequelize.define('comment', {
    	comment: {
        	type: DataTypes.STRING(100),
            allowNull: false,
        },
        created_at: {
        	type: DataTypes.DATE,
            allowNull: true,
            defaultValue: sequelize.literal('now()'),
        },
    }, {
    	timestamps: false,
    });
};

models/index.js

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

db.User = require('./user')(sequelize, Sequelize);
db.Comment = require('./comment')(sequelize, Sequelize);

module.exports = db;
...

config/config.json

{
	"development": {
    	"username": "root",
        "password": "[root 비밀번호]",
        "database": "nodejs",
        "host": "127.0.0.1",
        "dialect": "mysql",
        "operatorsAliases": false
    },
    ...
}

password 에는 mysql 비밀번호 입력 operatorsAliases는 보안에 취약한 연산자를 사용할지 여부이므로 false 입력!

관계 정의하기

1:N

models/index.js

...
db.User.hasMany(db.Comment, {foreignKey: 'commenter', sourceKey: 'id'});
db.Comment.belongsTo(db.User, {foreignKey: 'commenter', targetKey: 'id'});

module.exports = db;

한 명의 사용자는 여러개의 댓글 작성 가능하지만 댓글은 한명의 사용자만 참조 가능 hasMany는 1이 n개를 가짐을 의미 belongsTo는 n이 1개를 속함을 의미

1:1

db.User.hasOne(db.Info, { foreignKey: 'user_id', sourceKey: 'id'});
db.Info.belongsTo(db.User, { foreignKey: 'user_id', targetKey: 'id'});

N:M

db.Post.belongsToMany(db.Hashtag, { through: 'PostHashtag' });
db.Hashtag.belongsToMany(db.Post, { through: 'PostHashtag' });

belongsToMany 사용

N:M 관계 특성상 새로운 모델이 생성됨 (매핑테이블)

쿼리 알아보기

sequelize.js 쿼리를 통한 CRUD 작업하기 반드시 sequelize에서 정의한 자료형대로 넣어줘야 작동함

  • 로우 생성
INSERT INTO nodejs.users (name, age, married, comment) VALUES ('zero', 24, 0, '자기소개1');
const { User } = require('../models')
User.create({
	name: 'zero',
    age: 24,
    married: false,
    comment: '자기소개1',
});
  • users 테이블의 모든 데이터 조회
SELECT * FROM nodejs.users;
User.findAll({});
  • Users 테이블의 데이터 하나만 가져오는 SQL문
SELECT * FROM nodejs.users LIMIT 1;
user.find({});
  • attributes 를 통해 원하는 컬럼만 가져올 수 있음
SELECT name, married FROM nodejs.users;
User.findAll({
	attributes: ['name', 'married'],
});
  • where 옵션을 통해 조건 나열
SELECT name, age FROM nodejs.users WHERE married = 1 AND age > 30;
const { User, Sequelize: { OP } } = require('../models');
User.findAll({
	attributes: ['name', 'age'],
    where: {
    	married: 1,
        age: { [Op.gt]: 30 },
    },
});

결괏값 : 기혼자 30살을 넘은 유저들의 이름과 나이만 가져옴

연산자

  • Op.gt : 초과
  • Op.gte : 이상
  • Op.lt : 미만
  • Op.lte : 이하
  • Op.ne : 같지 않음
  • Op.or : 또는
  • Op.in : 배열 요소 중 하나
  • Op.notIn : 배열 요소와 모두 다름

  • 로우 수정
UPDATE nodejs.users SET comment = '바꿀 내용' WHERE id = 2;
User.update({
	comment: '바꿀 내용',
}, {
	where: { id: 2 },
})
  • 로우 삭제
DELETE FROM nodejs.users WHERE id = 2;
User.destroy({
	where: { id: 2 },
});