검색(Search)
데이터베이스에 있는 테이블에서 검색 조건에 맞는 데이터만 검색(select) 하기 위해서는 SELECT 할 때 WHERE 절을 사용하면 됩니다.
공통적으로 많이 사용하는 검색 조건은
- 검색 타입(검색할 테이블의 컬럼)
- 검색 조건(검색하고자 하는 키워드가 테이블의 컬럼 값과 일치하는지 또는 포함되는지에 대한 조건)
- 검색 키워드(검색할 테이블의 컬럼에서 검색할 키워드)

WHERE 절을 MyBatis Mapper XML에서 조건에 따라 처리되게 만들기 위해서는 <where>를 사용하면 됩니다.
검색 타입(searchType), 검색 조건(searchCondition), 검색 키워드(searchKeyword)
<select id="selectLunchMenuList">
SELECT TLM.*
FROM tb_lunch_menu TLM
<where>
<if test='searchKeyword != null and searchKeyword != ""'>
<choose>
<when test='searchType != null and searchType == "menuName"'>
<choose>
<when test='searchCondition != null and searchCondition == "like"'>
TLM.menu_name LIKE CONCAT('%',#{searchKeyword},'%')
</when>
<otherwise>
TLM.menu_name = #{searchKeyword}
</otherwise>
</choose>
</when>
</choose>
</if>
</where>
ORDER BY TLM.REG_DTM DESC
LIMIT ${pageStartRecordNo}, ${countPerPage}
</select>
검색 키워드가 있고 검색 타입이 menuName 이면 검색 조건(포함하면 like, 그렇지 않으면 일치)에 따라 검색
검색 키워드가 없거나 검색 타입이 일치하지 않으면 WHERE 절은 생성되지 않습니다.
점심 메뉴 리스트(selectLunchMenuList)와 점심 메뉴 리스트 수(selectLunchMenuListCount)에서 동일한 WHERE 절을 사용해야 합니다.
Mapper XML에서는 동일하게 사용되는 쿼리문을 분리하여 재사용할 수 있게 <sql>를 지원하고 있습니다.
<sql id="whereLunchMenuList">
<where>
<if test='searchKeyword != null and searchKeyword != ""'>
<choose>
<when test='searchType != null and searchType == "menuName"'>
<choose>
<when test='searchCondition != null and searchCondition == "like"'>
TLM.menu_name LIKE CONCAT('%',#{searchKeyword},'%')
</when>
<otherwise>
TLM.menu_name = #{searchKeyword}
</otherwise>
</choose>
</when>
</choose>
</if>
</where>
</sql>
<select>에서 <sql>를 가져오기 위해서 <include>를 추가하고 <include>의 refid 속성에 <sql>의 id을 입력하면 <sql>에 있는 쿼리문이 포함되게 됩니다.
검색(Search) 모듈 추가
1. src\db\mappers\mariadb\lunchmenu\lunchmenu-sql.xml 파일을 수정합니다.
:
<sql id="whereLunchMenuList">
<where>
<if test='searchKeyword != null and searchKeyword != ""'>
<choose>
<when test='searchType != null and searchType == "menuName"'>
<choose>
<when test='searchCondition != null and searchCondition == "like"'>
TLM.menu_name LIKE CONCAT('%',#{searchKeyword},'%')
</when>
<otherwise>
TLM.menu_name = #{searchKeyword}
</otherwise>
</choose>
</when>
</choose>
</if>
</where>
</sql>
<select id="selectLunchMenuList">
SELECT TLM.*
FROM tb_lunch_menu TLM
<include refid="whereLunchMenuList"/>
ORDER BY TLM.REG_DTM DESC
LIMIT ${pageStartRecordNo}, ${countPerPage}
</select>
<select id="selectLunchMenuListCount">
SELECT count(TLM.seq) AS listCount
FROM tb_lunch_menu TLM
<include refid="whereLunchMenuList"/>
</select>
:
2. src\api\v1\search.js 파일을 추가합니다.
// 검색
// HTTP 요청 req
const search = function(req) {
// 검색 타입
let searchType = req.query.searchtype;
if (searchType == undefined || typeof searchType == "undefined" || searchType == null) {
searchType = "";
}
// 검색 조건 - 일치(equal), 포함(like)
let searchCondition = req.query.searchcondition;
if (searchCondition == undefined || typeof searchCondition == "undefined" || searchCondition == null) {
searchCondition = "equal";
}
// 검색 키워드
let searchKeyword = req.query.searchkeyword;
if (searchKeyword == undefined || typeof searchKeyword == "undefined" || searchKeyword == null) {
searchKeyword = "";
}
// 검색 정보
const searchInfo = {
searchType : searchType,
searchCondition : searchCondition,
searchKeyword : searchKeyword
}
return searchInfo;
}
module.exports = search;
3. src\api\v1\lunchmenu.js 파일을 수정합니다.
:
const search = require('./search');
:
// 전체 점심 메뉴 리스트를 리턴합니다.
router.get('/', async function(req, res, next) {
console.log("REST API Get Method – Read All Lunch Menu.");
const searchInfo = search(req);
const result = {
result: 'success',
code: 200,
message: '',
data: [],
pagination: {}
};
let conn;
try {
conn = await getDBConnection();
const params = {
searchType : searchInfo.searchType,
searchCondition : searchInfo.searchCondition,
searchKeyword : searchInfo.searchKeyword
};
//const query = "SELECT count(seq) AS listCount FROM tb_lunch_menu";
let query = mybatisMapper.getStatement('apiserver.db.mappers.mariadb.lunchmenu',
'selectLunchMenuListCount', params, format);
// 전체 크기
const dataCount = await conn.query(query);
if (dataCount.length == 0) {
result.message = "데이터가 없습니다.";
} else {
// 결과에 숫자 타입(int(n, N), float(f, F), double(d, D), long(l, L))이 같이 옵니다. [ { listCount: 3n } ]
const totalCount = parseInt(dataCount[0].listCount);
// 페이지네이션 정보
// 전체 레코드 수 totalCount
// 페이지 크기 req.query.countperpage
// 페이지 번호 req.query.pageno
// 페이지 사이즈 req.query.pagesize
const paginationInfo = pagination(totalCount, req.query.pageno, req.query.countperpage, req.query.pagesize);
if (totalCount > 0) {
params.pageStartRecordNo = paginationInfo.pageStartRecordNo;
params.countPerPage = paginationInfo.countPerPage;
//const query = "SELECT * FROM tb_lunch_menu ORDER BY REG_DTM DESC";
query = mybatisMapper.getStatement('apiserver.db.mappers.mariadb.lunchmenu',
'selectLunchMenuList', params, format);
const data = await conn.query(query);
if (data.length == 0) {
result.message = "데이터가 없습니다.";
} else {
result.message = "데이터가 조회되었습니다.";
result.data = data;
}
} else {
result.message = "데이터가 없습니다.";
}
// 페이지네이션 정보
result.pagination = paginationInfo;
}
} catch (error) {
result.result = "fail";
result.code = 500;
if (error.code == "ER_NO_SUCH_TABLE") {
result.message = "테이블이 없습니다.";
} else {
result.message = "서버 오류가 발생하였습니다.";
}
console.log(error);
} finally {
if (conn) {
conn.release();
}
}
res.status(result.code).json(result);
});
점심 메뉴 API 테스트 (POSTMAN에서 확인)
1. 전체 점심 메뉴 조회
http://127.0.0.1:9000/api/v1/lunchmenus?searchtype=menuName&searchcondition=like&searchkeyword=%EB%B3%B6
%EB%B3%B6 → 볶
문자열 디코딩(https://dencode.com/)

{
"result": "success",
"code": 200,
"message": "데이터가 조회되었습니다.",
"data": [
{
"seq": 3,
"menu_name": "볶음밥",
"reg_dtm": "2025-01-17 13:37:26"
}
],
"pagination": {
"totalCount": 1,
"countPerPage": 10,
"pageSize": 10,
"startPageNo": 1,
"endPageNo": 1,
"lastPageNo": 1,
"pageNo": 1,
"pageStartRecordNo": 0,
"pageEndRecordNo": 0
}
}
'Vue.js 3 & NodeJS > 사내교육 - 점심 메뉴' 카테고리의 다른 글
| [7] Frontend 개발 - 읽기 뷰 (ReadView), 수정, 삭제 생성 (0) | 2026.08.03 |
|---|---|
| [6] Frontend 개발 - 등록 뷰 (AddView) 생성 (0) | 2026.08.03 |
| [4] Backend 개발 - API Server 개발, Node.JS + Paging (0) | 2026.08.03 |
| [3] Backend 개발 - API Server 개발, Node.JS + MyBatis3 (0) | 2026.08.03 |
| [2] Frontend 개발 (0) | 2026.08.02 |