8/31
·
TIL
Today I LearnedMapper#Mapper의 사용 목적Mapper는 객체 간 변환을 담당하는 컴포넌트로, 주로 DTO ↔ Entity 간 변환에 사용된다.비즈니스 로직과 데이터 변환 로직을 분리함으로써 코드의 가독성과 유지보수성을 높여준다.- 계층 분리: Controller, Service, Repository 간 데이터 전달을 명확히 분리- 중복 제거: 변환 로직을 한 곳에 모아 재사용 가능- 테스트 용이성: 변환 로직을 독립적으로 테스트 가능 #Mapper 구현 방식1. 수동 매핑직접 변환 로직을 작성- 장점: 세밀한 제어 가능- 단점: 코드량 증가, 반복 작업 많음public MemberDto toDto(Member member) { return new MemberDto(member...
8/30
·
TIL
Today I Learned테스트 코드#테스트 코드의 목적테스트 코드는 단순히 “코드가 잘 동작하는지 확인”하는 것을 넘어, 코드 품질 보증과 리팩토링 안전망 역할을 한다.- 버그 예방: 기능 변경 시 기존 기능이 깨지지 않았는지 빠르게 확인 가능- 문서화: 테스트 자체가 코드 사용 예시가 되어, 동작 방식을 이해하는 데 도움- 리팩토링 안전망: 구조 변경 시 기존 동작이 유지되는지 보장 #테스트의 종류단위(Unit) 테스트- 가장 작은 단위(메서드, 클래스)를 독립적으로 검증- 외부 의존성(DB, 네트워크 등)은 Mocking 처리- 예: `@Mock`, `@InjectMocks`를 사용한 Mockito 기반 테스트 통합(Integration) 테스트- 여러 모듈이 함께 동작하는 지 검증- 실제 DB,..
8/29
·
TIL
Today's Codekata# Count Salary CategoriesSELECT s.category, COALESCE(salary.accounts_count, 0) AS accounts_countFROM ( SELECT 'Low Salary' AS category UNION ALL SELECT 'Average Salary' UNION ALL SELECT 'High Salary') AS sLEFT JOIN ( SELECT CASE WHEN income = 20000 AND income 50000 THEN 'High Salary' END AS category, COALESCE(COUNT(*), 0) AS accounts_count FROM A..
8/28
·
TIL
Today's Codekata# Consecutive NumbersSELECT DISTINCT l1.num AS ConsecutiveNumsFROM Logs l1JOIN Logs l2 ON l1.id = l2.id + 1JOIN Logs l3 ON l1.id = l3.id + 2WHERE l1.num = l2.num AND l2.num = l3.num;# Product Price at a Given DateSELECT p.product_id, COALESCE(( SELECT new_price FROM Products WHERE product_id = p.product_id AND change_date // 카펫class..
8/27
·
TIL
Today's Codekata# The Number of Employees Which Report to Each EmployeeSELECT e.employee_id, e.name, COUNT(r.employee_id) AS reports_count, ROUND(AVG(r.age)) AS average_ageFROM Employees eINNER JOIN Employees r ON r.reports_to = e.employee_idGROUP BY e.employee_idORDER BY e.employee_id;# Primary Department for Each EmployeeSELECT e1.employee_id, COALESCE(e2.department_id, e1.d..
8/26
·
TIL
Today's Codekata# Find Followers CountSELECT user_id, COUNT(*) AS followers_countFROM FollowersGROUP BY user_idORDER BY user_id;# Biggest Single NumberSELECT COALESCE(( SELECT num FROM MyNumbers GROUP BY num HAVING COUNT(*) = 1 ORDER BY num DESC LIMIT 1), null) AS num;# Customers Who Bought All ProductsSELECT c.customer_idFROM Customer cGROUP BY c.customer_idHAVING COUNT(DISTIN..
8/25
·
TIL
뉴스피드 프로젝트AccessToken과 RefreshToken항목액세스 토큰리프레시 토큰목적사용자 인증 후, 리소스 접근 권한 부여액세스 토큰 만료 시, 새로운 토큰 발급사용처API 요청 시 헤더에 포함 (Authorization)토큰 재발급 요청 시 사용수명짧음 (몇 분 ~ 수십 분)김 (수 시간 ~ 수 일)보안 위험탈취 시 즉시 리소스 접근 가능탈취 시 장기적인 접근 가능성 있음저장 위치클라이언트 메모리, 쿠키 등보통 HttpOnly 쿠키 또는 보안 저장소서버 검증 방식JWT의 경우 자체 검증 가능보통 DB나 Redis에서 검증 필요동작 흐름 예시1. 로그인 성공 → 서버가 액세스 토큰 + 리프레시 토큰 발급2. 클라이언트는 액세스 토큰을 이용해 API 요청3. 액세스 토큰 만료 → 리프레시 토큰으로..
8/24
·
TIL
뉴스피드 프로젝트Session vs JWTSession 기반 인증서버에 사용자 상태 저장(stateful) → 클라이언트엔 세션ID만 쿠키로 전달(JSESSIONID)사용자가 요청을 보낼 때마다 쿠키에 담긴 세션ID로 서버가 상태를 조회해 인증을 처리 장점서버에서 세션을 무효화하면 즉시 로그아웃 가능민감정보는 서버에만 저장되어 노출 위험이 적음 단점서버 확장 시 세션 공유(Sticky Session, Redis 등) 필요쿠키 기반이라 CSRF 방어가 필수 JWT 기반 인증서버가 상태를 저장 X(stateless) → 토큰 자체에 사용자 정보와 만료 시간을 담아 서명클라이언트는 토큰을 보관하고 요청 시 헤더에 실어 보냄 → 서버는 서명과 만료만 검증 장점서버 확장에 유리 (무상태)게이트웨이, 외부 서비스 ..
8/23
·
TIL
Today's Codekata// 최댓값과 최솟값public class Solution { public String solution(String s) { String[] parts = s.split(" "); int min = Integer.MAX_VALUE; int max = Integer.MIN_VALUE; for (String part : parts) { int num = Integer.parseInt(part); min = Math.min(min, num); max = Math.max(max, num); } return min + " " + max; }}..
8/22
·
TIL
뉴스피드 프로젝트MapStruct를 활용한 DTO 매핑도메인 엔티티를 클라이언트 응답용 DTO로 변환하기 위해 MapStruct를 사용했다.컴파일 시점에 안전한 매핑 코드를 자동 생성해주므로, 런타임 없이 빠르고 안정적인 DTO 변환이 가능하다 활용 예시@Mapper(componentModel = "spring")public interface PostMapper { // PostRequest DTO -> Post Entity Post toEntity(PostRequest postRequest, User user); // Post Entity -> PostResponse DTO @Mapping(source = "user", target = "author", qualifiedByName..