일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- 알고리즘
- 주린이
- 객체지향
- 배당성장
- mco
- 오버라이딩
- XLF
- 잉여현금흐름
- 접근제어자
- 무디스
- 프로그래머스
- 금리인상
- 다형성
- S&P500
- javascript
- 제태크
- 백준
- FCF
- 그리디 알고리즘
- etf
- object
- 인플레이션
- StringBuffer
- 자바
- 미국주식
- 기업분석
- 주식
- Java
- 금리인하
- 현금흐름표
- Today
- Total
목록Spring (57)
오늘의하루
문제점 : 깊은 상속 관계의 DTO 무리들...레거시 프로젝트에서는 각각의 DTO들이 모두 깊은 상속 관계를 갖은 채 하나씩 정의되어 있으며 해당 DTO를 사용해서 모든 행위에 대해 사용하고 있었습니다.불필요한 데이터 전송요청과 응답에 불필요한 필드들이 포함되어 있습니다.유지보수 어려움새로운 필드 추가시 모든 DTO를 검토해야 할 수 있습니다.리팩토링 방향 : 상속에서 컴포지션으로비록 정상적으로 작동하고 있지만 앞으로도 계속해서 사용될 제품이기 때문에 데이터 전송의 효율성과 유지 보수성을 개선하기 위해 리팩토링을 결정했습니다. 처음 리팩토링 관련 이야기를 했을때 "이미 동작하는 프로젝트를 굳이 수정할 필요가 있는가?"라는 반응이였지만 내가 생각하는 중요하다고 생각드는 점을 강조하며 설득했습니다.명확성요청..
readonly 상태라면 영속성도 readonly일까? 라는 궁금증이 들어 테스트 코드를 작성하면서 알게 된 알아둬도 정말 쓸데 없는 내용을 공유하려고 합니다. Hibernate에서 readonly 힌트를 사용하면 해당 엔티티를 조회할 때 스냅샷을 만들지 않게 됩니다.이로 인해 더티 체킹이 발생하지 않으며 결국 수정 쿼리가 DB에 나가지 않게 됩니다.즉, readonly는 DB 쿼리 측면에서 수정할 수 없도록 만들어줍니다.그런데 readonly 상태에서도 엔티티의 필드를 수정해봤더니 수정 쿼리는 발생하지 않지만 1차 캐시에는 수정된 값이 반영되는 걸 알게 되었습니다.@Test@Transactional(readOnly = true)void queryHint() { // given Member m..
1. 벌크 연산 (Bulk Operation)이란?벌크 연산이란 N개의 데이터를 한 번에 UPDATE 또는 DELETE 하는 작업을 의미합니다.Spring Data JPA에서 벌크 연산을 수행하기 위해서는 @Modifying이 필요합니다.2. 왜 필요할까?Spring Data JPA에서는 기본적으로 Query 메서드의 반환 값을 getResultList() 또는 getSingleResult()를 통해 처리하는데 이는 SELECT에서만 사용 가능합니다.이러한 이유로 UPDATE와 DELETE는 수정 또는 삭제된 행의 개수를 반환하게 되기 때문에 반환 값을 맞추기 위해서 @Modifying이 필요한데 만약 사용하지 않는다면 아래와 같은 예외를 맞이할 수 있습니다.예외 클래스 : InvalidDataAcces..
Cascade Type 속성Cascade는 부모 객체의 상태 변화가 자식 객체에게 영향을 미칠지 여부를 설정하는 기능이며 양방향 관계에서 외래 키를 가지지 않는 객체를 부모라고 칭할 때 각 Cascade 유형의 의미는 다음과 같습니다.@Entitypublic class Team { ... @OneToMany(mapped by = "team") private List members = new ArrayList(); ...}1. PERSIST부모 객체를 저장할 때 자식 객체도 자동으로 DB에 저장할 수 있습니다.예를 들어, members.add(...)와 같이 부모 객체에 자식 객체를 추가한 후 Team 객체를 저장하면 Member 객체도 함께 저장됩니다.주의 사항: 자식 테이블에서 부..
API를 설계하다 보면 서로 다른 요청 데이터 타입에 공통 필드가 반복적으로 존재하는 경우가 많습니다.이 상황에서 새로운 공통 필드가 추가되거나 변경될 때 모든(1억개) DTO를 수정해야 하는 번거로움이 발생합니다. DTO(Data Transfer Object)를 쓰는 이유?"Controller에서는 DTO로 요청 정보를 받는 게 좋다."라는 말을 개발 공부를 시작했을 무렵 접하게 되었습니다.하지만 이유를 정확히 알지 못한 상태에서 사용해 오다가 이번에 JPA 공부를 하면서 그jangto.tistory.com1. 문제사항처음 API를 설계할 때 공통 내용을 요청받는 DTO를 각각 따로 만들었다고 가정합니다.예를 들어 BookRequest, AlbumRequest, MovieRequest라는 요청 DTO가..
"Controller에서는 DTO로 요청 정보를 받는 게 좋다."라는 말을 개발 공부를 시작했을 무렵 접하게 되었습니다.하지만 이유를 정확히 알지 못한 상태에서 사용해 오다가 이번에 JPA 공부를 하면서 그 의미를 더 깊이 이해하게 되었습니다. 해당 글에서는 Entity 대신 DTO를 사용해야 하는 이유를 정리했습니다.Entity와 DTO란 무엇일까?JPA와 같은 ORM(Object Relational Mapping) 기술을 사용할 때 Entity란 DB 테이블과 1:1로 매핑되는 클래스를 의미하며 각 필드는 테이블의 컬럼과 연결되어 애플리케이션에서 DB와 상호작용하는 도메인 모델의 역할을 합니다.DTO(Data Transfer Object)는 데이터 전송을 위한 전용 객체로써 주로 API 요청과 응답 ..
BeanPostProcessor는 Spring에서 빈이 등록되기 전 빈을 조작할 수 있는 강력한 기능입니다.빈 초기화 과정에서 BeanPostProcessor의 역할을 알아보고 @PostConstruct와의 실행 순서 차이에 따른 충돌 가능성을 알아보겠습니다.Bean이 등록되는 과정Spring Container가 빈을 등록할 때 간단하게 아래와 같은 순서로 진행됩니다.빈 정의 등록 - 빈 메타데이터를 등록합니다.빈 인스턴스 생성 - 빈 객체를 생성합니다. 의존성 주입 - 의존성을 주입합니다.빈 초기화 - 초기화 메소드를 호출합니다. 빈 등록 - 컨테이너에 등록합니다.BeanPostProcessor를 사용하면 빈 초기화 전후 단계에서 빈을 조작할 수 있습니다.※ BeanPostProcessor는 가장 우선..
Spring Cloud Gateway에서 API Gateway 필터 구성하기사용자 정의 필터를 생성하려면 AbstractGatewayFilterFactory를 상속 받은 후 apply 메서드를 구현한다.GatewayFilter를 반환해야 하며 GatewayFilter를 구현한 OrderedGatewayFilter로 생성하면 실행 순서를 지정할 수 있다.OrderedGatewayFilter는 Ordered도 구현하고 있는데 Ordered 객체 안에는 HIGHEST_PRECEDENCE (Integer.MIN_VALUE)와 LOWEST_PRECEDENCE(Integer.MAX_VALUE)가 있어서 가장 먼저 실행되야 하는것과 가장 마지막에 실행되어야 한는 필터의 순서를 쉽게 지정해줄 수 있다.추가 ) Filt..
서버 포트 번호 설정: server.port = 0Spring Boot에서 server.port=0으로 설정하면, 서버는 자동으로 사용 가능한 랜덤 Port 번호를 할당한다.이는 Spring Cloud에서 특히 유용하며 여러 애플리케이션 인스턴스를 각기 다른 Port로 실행해 Eureka와 같은 서비스 등록 서버에 유연하게 등록할 수 있다.Eureka 연동 시 랜덤 Port 번호 문제점Eureka는 기본적으로 Host 이름과 Port 번호를 결합하여 인스턴스를 등록하는데 포트가 0으로 설정하면 포트번호가 0번으로 등록되어서 같은 Host 이름을 가지게 되면 몇 개를 등록해도 1개만 등록된 것처럼 보이는 문제점이 있다.이를 해결하기 위해 고유한 인스턴스 ID 설정이 필요하다. [Eureka Client 설..
Proxy 내부 호출@Component@Slf4jpublic class A { public void external() { log.info("external"); internal(); } public void internal() { log.info("internal"); }}---@Aspect@Slf4jpublic class AllAspect { @Before("execution(* *(..))") public void doA(JoinPoint joinPoint) { log.info("aop = {}", joinPoint.getSignature()); }}위 상황에서 external()을 호출하면 doA 메서드에서 작..