[01 Operators란? ]
- 일단 DB에서 연산자(Operators)란 간단하게 특정 작업을 하기 위한 기호 또는 문자이다.
- 연산자의 종류로는 비교 연산자, 논리 연산자, 그리고 DBMS에서만 사용하는 기타 연산자들이 존재한다.
- 비교 연산자 : =, !=, >, < 등 좌우값을 비교하는 연산자
- 논리 연산자 : or, and 등 참(true), 거짓(false)을 가지고 비교하는 연산자
- 기타 연산자 : in, not in, between 등
- 저번 프로젝트에서는 MongoDB를 사용해서 Mongoose를 사용할 때도 이러한 연산자를 사용했는데 그 때는 아래와 같이 $ 표기를 이용해 연산자를 사용할 수 있었다.
- MySQL의 Sequelize에서도 그렇게 사용한 예제를 확인하고 비슷하게 $ 표기를 사용하려고 했으나 실패했고, 아래 방법으로 성공했다.
[02 Sequelize에서 Operators 사용하기 ]
(1) Op 모듈 import
- 먼저 sequelize에서 Op 모듈을 import해야 한다.
- 나는 index.ts 파일에서 Sequelize 연결 객체를 생성할 때 같이 import, export 해놓고 필요한 파일에서 import 했다.
import { Sequelize, Op } from "sequelize";
import config from "../config/config";
const sequelize = new Sequelize(config.development.database, config.development.username, config.development.password, {
host: config.development.host,
dialect: "mysql",
timezone: "+09:00",
dialectOptions: { charset: "utf8mb4", dateStrings: true, typeCast: true },
define: {
timestamps: true,
},
});
export { sequelize, Op };
(2) 연산자별 사용 예제
- 공식문서에 나와있는 연산자별 사용 예제는 다음과 같다.
- 엄청 많은 종류가 있으므로 한 번씩은 읽어보고 가장 적절한 연산자를 사용할 수 있도록 하는 게 좋을 것 같다.
const { Op } = require("sequelize");
Post.findAll({
where: {
[Op.and]: [{ a: 5 }, { b: 6 }], // (a = 5) AND (b = 6)
[Op.or]: [{ a: 5 }, { b: 6 }], // (a = 5) OR (b = 6)
someAttribute: {
// Basics
[Op.eq]: 3, // = 3
[Op.ne]: 20, // != 20
[Op.is]: null, // IS NULL
[Op.not]: true, // IS NOT TRUE
[Op.or]: [5, 6], // (someAttribute = 5) OR (someAttribute = 6)
// Using dialect specific column identifiers (PG in the following example):
[Op.col]: 'user.organization_id', // = "user"."organization_id"
// Number comparisons
[Op.gt]: 6, // > 6
[Op.gte]: 6, // >= 6
[Op.lt]: 10, // < 10
[Op.lte]: 10, // <= 10
[Op.between]: [6, 10], // BETWEEN 6 AND 10
[Op.notBetween]: [11, 15], // NOT BETWEEN 11 AND 15
// Other operators
[Op.all]: sequelize.literal('SELECT 1'), // > ALL (SELECT 1)
[Op.in]: [1, 2], // IN [1, 2]
[Op.notIn]: [1, 2], // NOT IN [1, 2]
[Op.like]: '%hat', // LIKE '%hat'
[Op.notLike]: '%hat', // NOT LIKE '%hat'
[Op.startsWith]: 'hat', // LIKE 'hat%'
[Op.endsWith]: 'hat', // LIKE '%hat'
[Op.substring]: 'hat', // LIKE '%hat%'
[Op.iLike]: '%hat', // ILIKE '%hat' (case insensitive) (PG only)
[Op.notILike]: '%hat', // NOT ILIKE '%hat' (PG only)
[Op.regexp]: '^[h|a|t]', // REGEXP/~ '^[h|a|t]' (MySQL/PG only)
[Op.notRegexp]: '^[h|a|t]', // NOT REGEXP/!~ '^[h|a|t]' (MySQL/PG only)
[Op.iRegexp]: '^[h|a|t]', // ~* '^[h|a|t]' (PG only)
[Op.notIRegexp]: '^[h|a|t]', // !~* '^[h|a|t]' (PG only)
[Op.any]: [2, 3], // ANY (ARRAY[2, 3]::INTEGER[]) (PG only)
[Op.match]: Sequelize.fn('to_tsquery', 'fat & rat') // match text search for strings 'fat' and 'rat' (PG only)
// In Postgres, Op.like/Op.iLike/Op.notLike can be combined to Op.any:
[Op.like]: { [Op.any]: ['cat', 'hat'] } // LIKE ANY (ARRAY['cat', 'hat'])
// There are more postgres-only range operators, see below
}
}
});
(3) 코드에 적용
- 프로젝트에 적용한 예는 다음과 같다.
- findByTime 메소드는 새로운 일정을 추가할 때 그 시간에 미리 등록한 일정이 있는지 확인하는 기능이다.
- 따라서 본인의 일정 중 시작 시간이 다른 일정의 start ~ finish 사이에 있거나, 끝나는 시간이 다른 일정의 start ~ finish 사이에 있는지 검사하는 로직이 필요했다.
- 이를 위해 or 연산자와 between 연산자를 사용했다.
- 이 때 두 개 이상의 입력값이 있는 연산자는 key와 value 모두 [ ] 로 감싸야 한다.
- between 의 경우 첫 번째값 이상 두 번째값 미만의 범위를 뜻하므로 주의해야 한다.
import { Op } from "./models";
import { Users } from "./models/user";
import { Schedules } from "./models/schedule";
import { IScheduleCreateInput } from "../interfaces/scheduleInput";
const Schedule = {
findByTime: async (fk_user_id: string, start: Date, finish: Date) => {
const schedule = await Schedules.findOne({
where: { [Op.or]: [{ start: { [Op.between]: [start, finish] }, finish: { [Op.between]: [start, finish] } }] },
include: { model: Users, where: { pk_user_id: fk_user_id } },
});
return schedule;
},
};
export { Schedule };
'엘리스 AI트랙 4기 > 프로젝트' 카테고리의 다른 글
[MySQL] csv 파일 import (0) | 2022.06.21 |
---|---|
[TypeScript Express] Sequelize의 Getters와 Setters (0) | 2022.06.18 |
[TypeScript Express] Sequelize 외래키로 참조 테이블 데이터 검색하기 (0) | 2022.06.16 |
[TypeScript Express] Sequelize로 MySQL 모델 Association 관계 설정하기 (0) | 2022.06.15 |
[TypeScript Express] Sequelize로 MySQL 기본 모델 생성하기 (0) | 2022.06.14 |