본문 바로가기
'다중 스킬' 검색 기능 구현 개발 시 요구사항은 간단하지만, 시스템 제약으로 구현이 복잡해지는 경우가 많다.최근 직원 목록 조회 API에 '다중 스킬' 검색 기능을 추가해야 했다. 요구사항 - 스킬 코드를 `/`로 구분된 하나의 문자열(예: "LANGU001/LANGU002/ LANGU003")로 전달한다. - 해당 스킬 중 하나라도 보유한 직원을 모두 검색해야 한다. 기존 쿼리는 `GROUP_CONCAT` 함수를 사용해 각 직원의 모든 스킬을 하나의 문자열로 가지고 있었다. 이 프로젝트를 해결하는 과정에서 마주친 제약과 그 해결책을 공유한다. 첫 번째 : `REGEXP`를 이용한 간단한 접근가장 먼저 떠오른 방법은 `GROUP_CONCAT`으로 생성된 문자열을 직접 검색하는 것이다. MySQL의 정규표현식 함수 `REGEX.. 2025. 9. 8.
@RequestBody의 유무에 따른 DTO 매핑 차이와 타임리프/React 컨트롤러 비교 Spring Boot로 웹 애플리케이션을 개발하다 보면, 컨트롤러에서 DTO(Data Transfer Object)에 데이터를 어떻게 매핑할지 고민이 된다. 특히, 프론트엔드가 React 등 SPA 방식인지, 아니면 타임리프(Thymeleaf) 같은 서버사이드 렌더링(SSR) 방식인지에 따라 컨트롤러 코드와 데이터 매핑 방식이 달라진다. @RequestBody 어노테이션의 유무에 따른 차이와, 실제 코드 예시를 통해 두 방식을 비교해보았다.1. React(REST API) vs. Thymeleaf(SSR) 컨트롤러 코드 비교REST API (React 화면)@RestController@RequestMapping("/qna")public class QnAController { @PostMapping(.. 2025. 7. 10.
[React] 컨포넌트에 props 전달 React 컴포넌트는 props를 이용해 서로 통신한다.모든 부모 컴포넌트는 props를 줌으로써 몇몇의 정보를 자식 컴포넌트에 전달할 수 있다.props는 HTML 어트리뷰트를 생각나게하지만, 객체, 배열, 함수를 포함한 모든 JS 값을 전달할 수 있다. props는 JSX 태그에 전달하는 정보이다.예를 들어 className, src, alt, width, height는 태그에 전달할 수 있다. 태그에 전달할 수 있는 props는 미리 정의되어 있다.아래애서 생성한 와 같은 어떠한 컴포넌트든 props를 전달할 수 있다.function Avatar() { return ( );}export default function Profile() { return ( );} 컴포넌트에 pr.. 2025. 5. 12.
[React] JSX JSX는 "JavaScript XML"의 약자, JS를 확장한 문법으로 JS 파일을 HTML과 비슷하게 마크업을 작성할 수 있도록 해준다.JSX 내에서는 중괄호를 사용해 JS 변수, 함수, 표현식을 자유롭게 삽입할 수 있다.하지만 JSX는 브라우저가 직접 이해하지 못하므로, Babel 같은 트랜스파일러가 JSX 코드를 일반 JS(React.createElement 등)로 변환한 뒤 실행한다. 컴포넌트를 작성하는 다른 방법도 있지만, 대부분 React 개발시에는 JSX의 간결함을 선호하며 대부분 코드 베이스를 JSX로 사용한다. 기존 Web은 HTML, CSS, JS를 기반으로 만들어 왔지만 이 시점에는 로직이 내용을 결정하는 경우가 많아졌다.그래서 JS가 HTML을 담당하게 되었다.이가 바로 React에.. 2025. 5. 12.
[React] 컴포넌트 컴포넌트 내보내기export default 접두사는 표준 JS이다. 이는 React에만 해당하지 않는다고 한다.이 접두사를 사용하면 다른 파일에서 가져올 수 있도록 파일에 주요 기능을 표시할 수 있다. 함수 정의function Profile( ) { } 을 사용하면 Profile이라는 이름의 JS 함수를 정의할 수 있다.React 컴포넌트는 일반 JS 함수이지만, 이름은 대문자로 시작해야한다. 그렇지 않을 경우 작동하지 않는다. 마크업 추가아래의 컴포넌트는 src 및 alt 속성을 가진 태그를 반환한다.는 HTML처럼 작성 되었지만 실제로는 JS이다. 이 구문을 JSX라 하며, JS 안에 마크업을 삽입할 수 있다.반환문은 아래의 컴포넌트처럼 한 줄에 모두 작성할 수 있다.return ; 하지만 마크업.. 2025. 5. 12.
[Vue3] vue Uncaught (in promise) ReferenceError: React is not defined script를 tsx 사용하며 문제가 생긴거같다.  plugin-vue-jsx를 설치해준다npm @vitejs/plugin-vue-jsx  vite.config.ts 파일에 아래와 같이 추가 및 수정 해준다import vueJsx from '@vitejs/plugin-vue-jsx'export default defineConfig({ plugins: [ vue(), vueJsx(), ]}) 2024. 11. 1.
[JavaScript] ES6 문법 ES6란?ES6는 2015년에 도입된 JS의 6번째 표준안이다.현대적인 코드를 사용하면, 코드가 간결해지고 생산성이 향상된다.변수 선언var : 재정의, 재선언 모두 가능let : 가변변수로 재정의가 가능, 재선언 불가능const : 불변변수. 재선언, 재정의 모두 불가능재선언 똑같은 이름의 변수를 다시 만드는것재정의 값이 지정된 변수에 값을 바꾸려는 것스코프 식별자(예: 변수명, 함수명, 클래스명 등)의 유효범위 //변수 선언var x = 2;//재정의x = 4;//재선언var x = 4; var의 문제점변수 선언이 유연하기 때문에 예기치 못한 값을 반환할 수 있음코드가 길어진다면 어디에서 어떻게 사용 될지 파악하기 힘듦함수 레벨 스코프로 인해 함수 외부에서 선언한 변수는 모두 전역 변수변수 선언문 이.. 2024. 11. 1.
[JAVA] Logger 사용하기 에러 발생시 디버깅을 항상 system.out.println()으로 진행해왔다.실무에서는 위처럼 찍지 않는다고한다.이유는 날짜, 시간, log level, thread 등등 나오지 않기 때문이다. 자세한 로그를 확인하기 위해 라이브러리를 사용하여 로그를 찍는다.SLF4J 인터페이스를 구현한 Logback을 사용해보았다. 로그 레벨로그 레벨에는 5단계가 있다.trace > debug > info > warn > error일반적으로 로컬 서버는 trace, 개발 서버는 debug, 운영 서버는 info로 한다.설정된 level 이하의 상태를 출력하지 않기 위해서는 properties에 아래 코드를 작성한다# 전체 로그 레벨 설정(default = info)logging.level.root=info# 패키지와.. 2024. 10. 28.
[Docker] Docker 명령어 시스템 정보#docker 버전 및 상세 정보docker version#docker 버전 및 빌드 버전 한줄 요악docker -v#docker 시스템 전체 정보docker system info#서버 실시간 이벤트 확인docker system events#docker 디스크 용량 확인docker system df#docker 허브 로그인docker login -u {ID} Image 명령어#목록 확인docker iamges 또는 docker image ls#모든 이미지 목록docker images -a#상세 정보docker image inspect (이미지명 또는 이미지 ID)#docker hub 이미지 검색docker search (옵션) (검색어)#옵션 사용 예제docker search --filter .. 2024. 10. 25.