MySQL
쿼리 추가
페이지 목록에서 워크플로우를 추가하여 쿼리 스텝을 추가할 수 있습니다.
워크플로우 스텝 사이드바에서 MySQL 데이터 소스를 선택하면 쿼리 입력 창이 나타납니다.
데이터 소스 추가 방법은 MySQL 데이터 소스 가이드를 참고해주세요.
기본 쿼리 작성
Hops에서는 일반적인 SQL 문법을 모두 사용할 수 있습니다. 데이터를 조회하거나 수정하는 모든 SQL 명령어를 사용할 수 있습니다.
-- 기본적인 SELECT 쿼리
SELECT * FROM customer;
-- WHERE 절을 사용한 필터링
SELECT id, name FROM customer WHERE advertisement_agreed;
-- JOIN을 사용한 테이블 연결
SELECT payment.id, payment.created_at, customer.name
FROM payment
JOIN payment_method ON payment.payment_method_id = payment_method.id
JOIN customer ON payment_method.customer_id = customer.id;
템플릿 문법 활용
템플릿 활용 방법에는 두가지가 있습니다.
{{}}
: JavaScript 표현식을 사용할 수 있습니다. 홉스 내에 있는 상태와 변수를 사용할 수 있습니다.{{$ }}
: 타입에 맞추어 SQL escape 처리가 됩니다.
예를 들어{{$ 'abc' }}
라는 코드는 string 타입에 맞추어SELECT abc
가 아닌SELECT 'abc'
로 해석됩니다.
-- 기본 사용
SELECT {{ 'name' }} FROM customer; -- SELECT name FROM customer와 동일한 결과. customer 테이블의 name 컬럼을 조회합니다.
SELECT {{$ 'name' }} FROM customer; -- SELECT 'name' FROM customer와 동일한 결과. `'name'`이라는 문자열 타입의 값이 결과로 나옵니다.
-- 조건부 WHERE 절
SELECT * FROM customer
WHERE
({{$ searchInput.value }} = '' OR name LIKE '%{{ searchInput.value }}%')
AND advertisement_agreed = {{$ advertisementAgreedCheckbox.checked }}
-- 배열 활용
SELECT * FROM payment
WHERE status IN (
{{ statusMultiSelect.values.length == 0 ? 'NULL' : statusMultiSelect.values.map(v => '${v}').join(',') }}
)
SQL Escape
SQL injection 공격을 방지하고 데이터 타입의 안전성을 보장하기 위해서는 적절한 escape 처리가 필요합니다.
Hops에서는 {{$ }}
구문을 통해 자동 SQL escape 처리를 지원합니다.
-- 기본 문자열 escape
SELECT * FROM customer WHERE name = {{$ textField1.value }}
-- -> SELECT * FROM customer WHERE name = 'textField1.value'
-- 숫자 타입 escape
SELECT * FROM payment WHERE points_rate > {{$ numberField1.value }}
-- -> SELECT * FROM payment WHERE points_rate > 100
-- 날짜 타입 escape
SELECT * FROM payment WHERE created_at = {{$ dateField1.value }}
-- -> SELECT * FROM payment WHERE created_at = 'dateField1.value'
변수 사용하기
다음과 같은 방식으로 변수를 사용할 수 있습니다.
1. 페이지 변수 사용
페이지에 등록된 변수는 page.변수명
형식으로 사용합니다.
자세한 내용은 페이지 변수 이해하기 문서를 참고해주세요.
SELECT * FROM customer WHERE id = {{page.userId}};
2. 워크플로우 입력값 사용
워크플로우에 정의된 입력값은 inputs.변수명
형식으로 사용합니다.
자세한 내용은 워크플로우 변수 값 가져오기 문서를 참고해주세요.
SELECT * FROM payment
WHERE created_at BETWEEN CAST({{$ inputs.startDate }} AS DATE) AND CAST({{$ inputs.endDate }} AS DATE);
3. 이전 스텝의 결과값 사용
이전 스텝의 결과값은 outputs.스텝명
형식으로 사용합니다.
자세한 내용은 워크플로우 스텝의 결과 값 가져오기 문서를 참고해주세요.
SELECT * FROM payment
WHERE payment_method_id = {{outputs.step1.data[0].payment_method_id}};
4. 컴포넌트 상태값 사용
페이지 내 컴포넌트의 상태값은 컴포넌트명.상태명
형식으로 사용합니다.
자세한 내용은 컴포넌트 문서를 참고해주세요.
SELECT * FROM customer
WHERE name LIKE '%{{searchInput.value}}%';
쿼리 결과값
SQL 쿼리를 실행하면 결과값이 data: Record<string, unknown>[]
와 같은 구조로 반환됩니다.
data
: 쿼리 결과를 담고 있는 최상위 객체Record<string, unknown>[]
: 컬럼명을 key로, 해당 값을 value로 가지는 객체들의 배열
결과값 활용하기
-- 첫번째 SQL 스텝 쿼리
SELECT id, name FROM customer;
-- 결과값 구조
{
data: [
{ id: 1, name: "John Doe" },
{ id: 2, name: "Jane Doe" }
]
}
-- 두번째 JavaScript 스텝 쿼리
return outputs.step1.data.map(item => item.name);
주의사항
- 템플릿 내에서는 SQL 인젝션을 방지하기 위해 적절한 이스케이프 처리가 필요합니다.
- 복잡한 조건문이나 데이터 처리가 필요한 경우, JavaScript 스텝을 먼저 실행한 후 그 결과를 SQL 쿼리에서 사용하는 것이 좋습니다.
- 대량의 데이터를 다루는 경우 적절한 LIMIT과 페이지네이션을 사용하는 것이 권장됩니다.
예시: 검색 기능 구현
다음은 검색어와 카테고리 필터를 적용한 제품 검색 쿼리의 예시입니다:
SELECT payment.id, payment.created_at, customer.name
FROM payment
JOIN payment_method ON payment.payment_method_id = payment_method.id
JOIN customer ON payment_method.customer_id = customer.id
WHERE
(
customer.name LIKE '%{{searchInput.value}}%' OR
payment.id LIKE '%{{searchInput.value}}%'
)
AND payment.created_at BETWEEN CAST({{$ inputs.startDate }} AS DATE) AND CAST({{$ inputs.endDate }} AS DATE)
ORDER BY payment.created_at DESC
LIMIT {{$ paymentTable1.page.limit }}
OFFSET {{$ paymentTable1.page.offset }}
이 예시는 검색어, 페이지네이션을 모두 포함하고 있습니다.