본문 바로가기

전체 글18

paging /* PAGINATED FRAG TOP */SELECT * FROM ( SELECT ROWNUM RN, SOMETHING_TABLE.* FROM (위 쿼리 조각과 아래 쿼리 조각을 한 세트로 사용하고, 인라인 뷰에서 탐색하고자 하는 테이블 조건을 작성한다./* PAGINATED FRAG BOTTOM */ ) BASE WHERE ROWNUM 페이징은 원천 데이터가 존재하는 DB부터 프론트 엔드 방향으로 역순으로 설계한다. DB > BE > FE전체 데이터를 가져와서 Java에서 자르는 것은 성능상 절대 피해야 한다.Oracle 버전에 따라 페이징 쿼리 방식이 나뉜다.- Oracle 11g 이하 (`INLINE VIEW` + `ROWNUM`)- Oracle 12c 이상 (`OFFSET.. 2026. 7. 13.
[Gradle] 프로젝트 빌드 시 JAVA_HOME 대신 프로젝트 전용 JDK 버전 사용하기 프로젝트를 여러 개 동시에 돌리다 보면 필히 버전 의존성 문제를 마주치게 된다.나는 Gradle로 빌드하고자 하는 프로젝트가 Java 11 바이트코드로 빌드된 caffeine 3.1.8 라이브러리를 사용하고 있어 JDK 11 버전이 필요했는데, JAVA_HOME을 JDK 8버전(Azul Zulu)으로 세팅해두어서 8 버전으로 실행된 Gradle의 kapt가 해당 라이브러리를 읽지 못하며 빌드에 실패했다. 프로젝트별 JDK 버전 의존성 관리법그렇다면 이 프로젝트를 빌드하기 위해서는 어떻게 하면 될까? JAVA_HOME에 저장된 JDK를 다시 11 버전으로 변경해야 할까?물론 그렇게 해도 되겠지만 서로 다른 JDK 버전을 사용하는 여러 개의 프로젝트를 동시에 빌드해야 하는 경우에는 한계가 있다.이러한 버전 .. 2026. 7. 9.
[MyBatis] test="stringValue == 'Y'" 에서 NumberFormatException 문제 상황문제가 되었던 부분의 조건문이다. AND A.COLUMN = #{condition}Java 측에서 stringValue에 할당한 값이 "Y" 였음에도 NumberFormatException이 발생한다.이는 stringValue에 String 타입의 값을 할당하였으나, 실제로 MyBatis에서 작성한 'Y'는 Char 타입에 해당되기 때문이다.이러한 현상이 나타나는 까닭은 정확히는 MyBatis의 문제라기보단 OGNL(Object-Graph Navigation Language) 인터프리터의 영향 때문인데, OGNL 인터프리터는 'Y'는 Char 타입으로, 'YY' 혹은 "Y"는 String 타입으로 해석한다.또한 Java에서는 Char 타입을 코드 값으로 저장하고 있다. 그래서 Char 타입.. 2025. 6. 29.
[MyBatis] XML 세미콜론 포함 시 SQLSyntaxErrorException Datagrip에서 동일 쿼리문 수행했을 때 정상 작동하나, Server에서 MyBatis를 통해 반환하는 값은 아래와 같았다.### Error querying database. Cause: java.sql.SQLSyntaxErrorException: ORA-00933: SQL command not properly ended### The error may exist in URL [jar:file:/{.xml_파일_절대경로}]### The error may involve {mapper_패키지_경로.mapper_쿼리_id명}-Inline### The error occurred while setting parameters### SQL: {오류 대상 쿼리문, (parameter 위치의 경우 ? 로 기재됨)};.. 2025. 4. 3.
[JavaScript] Object key 동적으로 추가하기 Object 변수에 'foo'라는 이름의 key를 동적으로 추가해보자.정적인 추가const obj = {};const key = 'foo';obj.key = 'bar';console.log(obj);>>> { key: 'bar' } // 'key'라는 이름의 key가 저장된다. (의도한 동작 X)obj.foo = 'bar'; // 따라서 정적인 방식에서는 key 이름을 직접 명시해야 한다.console.log(obj);>>> { foo: 'bar' }동적인 추가const obj = {};const key = 'foo';obj[key] = 'bar';console.log(obj);>>> { foo: 'bar' }; // 'foo'라는 이름의 key가 저장된다. 2025. 3. 4.
[Swiper.js] 복제 DOM 이벤트 부착 시점의 문제 Swiper를 사용할 때, autoplay 속성을 활성화하면 슬라이드 간의 자연스러운 움직임을 나타내기 위해서 원본 DOM이 앞 뒤로 복제된다. 그래서 실제로 내가 타겟으로 삼은 DOM 요소들은 중앙에서 나타나고, Swiper 옵션이 적용됨과 동시에 앞 뒤로 duplicate 라는 이름의 클래스를 가진 복제 DOM들이 자동으로 생성된 것을 확인할 수 있다. (그래서 슬라이드가 전환될 때마다 activeIndex, realIndex를 찍어보면 본래 의도한 순서와 다르게 실제 의도한 수 + 총 원본 갯수 의 수로 나타난다.) 이 때 중요한 것은 원본 객체의 이벤트 리스너 부착 시점이다. 예를 들어 제품 정보를 나타내는 영역이었다고 가정해보자. 하나의 제품 정보에는 장바구니 담기, 좋아요 버튼, 제품 상세 페.. 2025. 2. 9.