본문 바로가기

IT177

[Spring Boot] 네이티브 쿼리 vs JPQL 네이티브 쿼리@Query( value = "SELECT * FROM users WHERE age >= 20", // 일반적인 SQL nativeQuery = true)List findAdults();DB에 직접 SQL 날림JPA와 별개로 동작결과를 객체로 매핑만 해줌JPA 생태계와 독립적으로 날리는 쿼리이다.즉 DB 종속적이므로 컬럼명이나 테이블명이 변경되면 유지보수가 번거로울 수 있다. JPQL(Java Persistence Query Language)일반적인 SQL과 문법이 거의 비슷하지만 살짝 다르다.@Query( value = "SELECT * FROM User WHERE age >= 20", // User는 테이블명이 아닌 엔티티명. 대소문자 구별함)List findAdults();네이티.. 2025. 12. 24.
[React/TypeScript] 통합 회원관리 시스템(IAM) 프론트 구현 기록 IAM 백엔드 구현 기록 [Spring Boot] 통합 회원관리 시스템(IAM) 구현 기록사내에서 개발한 통합 회원관리 시스템 IAM(Identity and Access Management) 구현 기록.참고: 분류를 Spring Boot로 해두었지만 코드는 없고 정책 관련 내용만 있습니다. JWT(JSON Web Token)를 통한 토큰 방식 사doringri.tistory.com fetch는 코드를 간결하게 작성하기 위해선 오류 처리나 json 파싱 등 래핑 작업이 불가피하여 초기세팅이 좀 더 편하고 번들 사이즈도 axios에 비해 가벼운 ky 사용ky에서 지원하는 beforeRequest, beforeError, afterResponse hook을 통해 토큰 관련 로직 처리beforeRequest에서.. 2025. 12. 20.
[PostgreSQL] pg_cron 익스텐션 환경설정 SSO 서비스를 만들면서 리프레시 토큰을 Redis가 아닌 PostgreSQL에 저장하기로 결정했었다.토큰 rotation(교체)최대 기기가 3개라면 가장 오래된 세션 제거위의 요구사항들을 위해선 조건 기반 조회가 필요한데, Redis보다 RDBMS가 해당 작업을 수행하는 데 더 적절하기 때문이었다. 하지만 기간이 만료되거나 로그아웃으로 인해 회수된 리프레시 토큰들은 Redis와는 달리 자동으로 로우가 삭제되지 않는다.그래서 특정 시간에 로우들을 지워줄 스케줄러가 필요한 상황이었고 SSO 서비스보다는 DB 레벨에서 처리해주는 게 더 안정적이라고 생각했다. 스케줄러 대신 트리거를 쓰자는 의견도 나왔지만 DB에 부하가 일어날 수 있고, 리프레시 토큰 삭제 작업은 정기적으로 실행되는 것이 더 알맞다고 판단하여.. 2025. 12. 15.
[IT/Web] 쿠키 저장 정책(Set-Cookie, SameSite) 온프레미스 배포 환경(non-ssl)에서 쿠키 저장이 안 됐던 이유에 대해 정리.브라우저 정책상 Secure가 false인 쿠키는 SameSite가 무조건 Lax, Strict여야 저장하기 때문에 Lax로 설정하였음.1. 문제 상황프론트: http://192.168.0.60/iam백엔드(API): http://192.168.0.60:9100refreshToken 쿠키: HttpOnly + SameSite=Lax + Domain 없음 + Path="/"로그인 API: POST http://192.168.0.60:9100/auth/login증상:/iam에서 로그인하면 쿠키 저장 안 됨요청시 옵션에 credentials: "include" 를 넣으면 저장됨백엔드를 nginx 설정으로 프록시하면 저장됨2. 원인.. 2025. 12. 11.
[TanStack Query] Query Key factories로 Query Key 관리하기 TanStack Query를 사용할 때는 Query Key 관리를 강조하는 경우가 많았다.공식문서의 링크에 Query Key factories 패턴을 소개하고 있다. https://tkdodo.eu/blog/effective-react-query-keys Effective React Query KeysLearn how to structure React Query Keys effectively as your App growstkdodo.eu const todoKeys = { all: ['todos'] as const, lists: () => [...todoKeys.all, 'list'] as const, list: (filters: string) => [...todoKeys.lists(), { fil.. 2025. 12. 5.
[Kotlin] 자주 쓰는 문법 사이드 프로젝트에서 백엔드 개발언어가 코틀린으로 정해짐.코틀린으로 개발해본게 이미 2-3년 전이라 다시 학습을 해야하는 상황..백엔드 개발자분이 자주 쓰는 문법을 설명해주신 것들 + 개인적으로 찾아본 것들을 정리함. 타입스크립트와 굉장히 유사한 부분이 많다. 구조 분해 할당 가능// data class에서의 구조분해 할당data class User(val id: Long, val name: String)val user = User(1, "SK")val (id, name) = user// 함수 구조분해 할당 (Pair가 data class임)fun coordinate(): Pair { return 10 to 20}val (x, y) = coordinate()// Map의 구조분해 할당 (iterate.. 2025. 11. 27.
[Spring Boot] 통합 회원관리 시스템(IAM) 구현 기록 사내에서 개발한 통합 회원관리 시스템 IAM(Identity and Access Management) 구현 기록.참고: 분류를 Spring Boot로 해두었지만 코드는 없고 정책 관련 내용만 있습니다. JWT(JSON Web Token)를 통한 토큰 방식 사용 이유구현하려는 것은 SSO(Single Sign On)였음.그래서 세션 방식을 사용한다면 각 서비스들에서 로그인 세션을 검증하기 위해 매번 중앙 서버에 확인을 해야 함. 결국 중앙 서버에 부하가 가해짐.그래서 서비스 개수가 늘어나더라도 각 서비스에서 관리하도록 하는 stateless한 토큰 방식이 좀더 적절.라이브러리는 jjwt를 사용하였다. 발급하는 토큰 종류보편적인 방식과 같이 액세스 토큰(Access Token)과 리프레시 토큰(Refresh.. 2025. 11. 26.
[JavaScript] DFS 상태 트리 https://doringri.tistory.com/92 [Python] DFS(깊이우선탐색) 알고리즘파이썬 알고리즘 문제풀이 입문(코딩테스트 대비) 강의 - 인프런 파이썬(Python)을 이용해 코딩 테스트 문제 풀이를 합니다., 개발자 취업 & 이직을 위한 핵심 코스 📝코딩테스트 대비 파이썬 알고doringri.tistory.com위는 파이썬 코드 버전. const n = 3;const ch = Array(n).fill(0);function DFS(v) { if (v === n) { // n까지 갔을때 종료 const subset = []; for (let i = 0; i 부분집합을 구하는 경우는 생각보다 많은 것 같다...BFS랑 같이 암기해두자. 2025. 11. 8.
[JavaScript] 가장 먼 노드 (BFS 그래프 알고리즘) 프로그래머스 Lv. 3 '가장 먼 노드' Solved-Algorithm/JavaScript/프로그래머스/3/49189. 가장 먼 노드 at main · ParkBible/Solved-AlgorithmThis is an auto push repository for Baekjoon Online Judge created with [BaekjoonHub](https://github.com/BaekjoonHub/BaekjoonHub). - ParkBible/Solved-Algorithmgithub.com 거리를 묻는 문제인만큼 전형적인 BFS 포맷으로 풀 수 있는 문제이며, 인접 노드 테이블 대신 간선 좌표를 주기 때문에 변환이 필요하다. function solution(n, edge) { const gr.. 2025. 11. 7.
[JavaScript] 함수 4장 내용. 자바스크립트 함수의 특징자바스크립트 함수는 일급 객체(first-class object)로 다루어짐즉 변수에 할당되거나 함수에 파라미터, 반환값으로 사용되는 등, '값'처럼 다룰 수 있음다른 함수를 인수로 받거나 반환하는 함수를 고차 함수라고 함함수에 파라미터로 넘긴 변수는 값이 '복사'됨, 즉 함수 내에서 값이 변경되어도 외부에선 그대로임하지만 객체를 넘겼을 경우 함수 내부에서 객체의 속성값을 변경하면 외부에도 영향을 줌 (엄격 모드 제외) 함수 선언문function 키워드를 통해 이름 있는 함수를 정의하는 방식호이스팅이 발생하여 정의하기 전에도 호출할 수 있음foo();function foo() { console.log("Hello, World!");} 함수 표현식동일하게 funct.. 2025. 11. 2.
[TypeScript] Null, Undefined 체크 동등 연산자(==)를 사용하면 Null과 Undefined 체크를 동시에 할 수 있다.동등 연산자를 사용하는 얼마 안되는 경우 중 하나다. let value = null;console.log(value == null); // truevalue == undefined;console.log(value == null); // true data?.value != null 처럼 옵셔널 체이닝에도 유용하다. Nullish Coalescing Operator(널 병합 연산자, ??)를 사용하면 Null, Undefined일 때 줄 값을 설정할 수 있다.let value = null;console.log(value ?? 1); // 1value == 0;console.log(value ?? 1); .. 2025. 10. 31.
[React] 훅 안에서 정의한 함수의 클로저 문제 훅 안에서 내부 함수를 정의하고 그 안에서 state를 쓸 때는 클로저 문제가 발생한다.useEffect(() => { const handleVisibility = () => { if (state !== "stopChecking") { // state가 바뀌어도 모름 console.log("visible"); } } document.addEventListener("visibilitychange", handleVisibility); return () => document.removeEventListener("visibilitychange", handleVisibility);}, []); 이런 경우 useEffect가 실행될 시점의 state 값을 캡쳐하고 그 값은 갱신되지 .. 2025. 10. 28.
[TypeScript] 문자열 key 검증하기 그저께 실무에서 고민했던 부분 정리... type Flag = { name: string; age: number;}const myFlag: Flag = { name: "doringri", age: 10};const getValue = (key: string): number | null => { return myFlag[key] ?? null;}const val = getValue("age") as number ?? 20;위의 코드는 as number로 타입을 단언해주고 있다.하지만 타입 단언은 대부분의 경우에서 타입 안전성이 낮다.getValue()에서 null을 체킹할 필요 없이 컴파일 단계에서부터 올바른 key인지 체크할 수 있다면 DX가 더 향상될 것이다. const getValue = (.. 2025. 10. 28.
[JavaScript] 타입 1장 내용. 원시 타입총 7가지가 있으며, 객체와 달리 속성이나 메서드를 가지고 있지 않다.하지만 대응하는 래퍼 객체가 존재하기 때문에 속성을 사용 가능하다.예를 들어 "doringri"라는 문자열은 String이라는 래퍼 객체가 존재하기 때문에 .length 속성을 사용 가능하다. Number자바스크립트는 정수와 부동소수점을 구분하지 않기 때문에 1과 1.0은 같은 값이다.내부적으로 배정밀도(64비트) 부동소수점 방식으로 숫자를 다룬다.3.14처럼 값을 직접 표현하는 것을 리터럴이라고 한다.표현할 수 있는 부동소수점 리터럴의 최대 크기는 대략 2의 1024승이다.오차 없이 표현할 수 있는 최댓값은 Number.MAX_SAFE_INTEGER이다. BigInt부동소수점의 범위를 벗어나는 큰 정수를 다룰 때.. 2025. 10. 21.
[JavaScript] 클로저 3장 내용. 클로저를 통한 정보 은닉function createCounter() { let count = 0; return function counter() { return ++count; }}const counter1 = createCounter();const counter2 = createCounter();console.log(counter1()); // 1console.log(counter2()); // 1count라는 변수에는 오로지 counter 함수에서만 접근이 가능하므로, 정보 은닉의 기능을 한다. 커링여러 개의 파라미터를 받는 함수를 하나의 파라미터만 받는 함수로 연속적으로 변환하는 함수형 프로그래밍 기법. 클로저를 통한 부분 적용 함수를 이.. 2025. 10. 14.