BACKEND 15

[Architecture]헥사고날 아키텍처 (Hexagonal Architecture

🔷 헥사고날 아키텍처(Hexagonal Architecture)란?목적: 비즈니스 로직(도메인, 유스케이스)을 외부 기술(DB, UI, 메시지 큐, API 등)로부터 분리해서 핵심 로직을 안정적으로 보호하고, 기술 요소는 쉽게 교체할 수 있도록 하는 아키텍처 패턴다른 이름: Ports and Adapters 패턴🧩 핵심 개념 1. 애플리케이션 코어 (Application Core)도메인 모델(엔티티, 값 객체 등)유스케이스(애플리케이션 서비스)외부 기술에 전혀 의존하지 않는 순수한 로직포트 (Ports)코어와 외부 세계를 연결하는 추상 인터페이스두 가지로 나뉨인커밍 포트 (Incoming Port)→ 외부에서 코어를 호출할 때 사용 (예: REST Controller가 호출하는 UseCase 인터페..

BACKEND 2025.09.04

[Architectural Pattern] CQRS (Command Query Responsibility Segregation)

데이터를 변경하는 기능(쓰기)과 데이터를 조회하는 기능(읽기)을 분리하는 패턴 CQRS 방식쓰기(Command)와 읽기(Query)를 위한 서로 다른 모델을 만듭니다. 종류 구분Command Model (쓰기 모델)Query Model (읽기 모델)목적데이터의 생성, 수정, 삭제 (쓰기)데이터의 조회 (읽기)데이터 모델복잡한 모델객체지향적이고 풍부한 엔티티 모델비즈니스 규칙과 로직을 포함데이터 정합성(Consistency) 유지에 초점단순한 모델데이터베이스 스키마와 유사한 평면적(flat) 모델조회에 필요한 데이터만 포함성능(Performance)에 초점주요 작업Command 처리(예: CreateUserCommand, UpdateProductPriceCommand)Query 처리(예: GetUserBy..

BACKEND 2025.08.29

[java]리플렉션 (reflection)

reflection ** 반사, 반영 프로그램이 실행되는 동안(런타임에) 클래스, 메서드, 필드, 생성자 등의 내부 정보를 동적으로 조사하고, 조작할 수 있는 자바 API의 기능.쉽게 말해, 평소에는 코드를 직접 짜야만 할 수 있는 일(객체 생성, 메서드 호출 등)을, 코드가 실행되고 있는 도중에 동적으로 처리하는 기술입니다. 리플렉션이 할 수 있는 일 (핵심 기능)리플렉션은 주로 java.lang.reflect 패키지의 클래스들을 통해 다음을 수행합니다.클래스 정보 조회: 클래스의 이름, 필드, 메서드, 생성자 목록을 가져옵니다.객체 생성: 클래스 이름만 가지고 새로운 객체를 만듭니다.메서드 호출: 메서드 이름을 가지고 해당 메서드를 실행합니다.필드 값 접근/변경: 필드 이름을 가지고 값을 읽거나 바..

BACKEND 2025.08.22

[java] Spring AOP(Aspect-Oriented Programming)

흩어진 관심사를 한곳에 모아주는 기술 쉬운 비유: 아파트 경비원아파트에 사는 모든 주민들은 현관문을 열고 들어갈 때, 공통적으로 비밀번호를 누르거나 카드를 찍는 행동을 해야 합니다.주민이 하는 일 (핵심 관심사): 주민의 본업(집에 들어가 쉬거나, 친구를 만나는 등)비밀번호 누르기 (흩어진 관심사): 모든 사람이 반복적으로 해야 하는 공통적인 일만약 이 비밀번호 입력 로직이 주민 한 명 한 명의 행동 방식(걸음걸이, 말하는 방식 등)에 포함되어 있다면, 경비 시스템을 바꾸거나 새로 추가할 때 모든 주민에게 "새로운 비밀번호 누르는 법을 배워라"고 알려줘야 할 겁니다. 매우 비효율적이죠.AOP는 이 문제를 다음과 같이 해결합니다."비밀번호를 누르는 일"이라는 공통적인 로직을 따로 분리해서, 경비원(Aspe..

BACKEND 2025.08.22

[java]ThreadLocal 사용법

ThreadLocal은 각각의 쓰레드 별로 별도의 저장공간을 제공하는 컨테이너 == 물건보관 창고 "각각 물건을 보관하면 각각 물건을 잘 보관할수 있게 겹치거나 사라지지 않게"일반적으로 변수는 여러 스레드에 의해 공유될 수 있다. 만약 여러 스레드가 동시에 같은 변수를 읽고 쓰게 되면, 데이터가 꼬이거나 예상치 못한 오류가 발생할 수 있다. 이를 해결하기 위해 synchronized나 Lock 같은 동기화 메커니즘을 사용하기도 하지만, 이는 스레드가 순서를 기다려야 하므로 성능 저하를 일으킬 수 있다. // 각 스레드마다 독립적인 사용자 이름을 저장할 ThreadLocal 변수 private static final ThreadLocal userContext = new ThreadLocal();pub..

BACKEND 2025.08.21

[Architecture]멀티테넌시(Multi-tenancy) -Shared Schema 방식

클라우드 환경 확산과 함께 SaaS(Software as a Service) 모델이 대중화되면서 하나의 시스템을 여러 고객이 공유하는 방식 필요. 멀티테넌트는 하나의 소프트웨어(또는 서버, DB)가 여러 **고객(테넌트, Tenant)**을 동시에 지원하는 구조 Shared Schema 방식을 기반 백엔드에서 만들어보쟈 “요청 들어오면 테넌트 확인 → 서비스에서 테넌트 적용 → DB 저장/조회 시 필터링” * Shared Schema하나의 DB, 하나의 테이블을 여러 테넌트가 공유테이블 컬럼으로 테넌트 구분 (tenant_id)방식 DB 테이블 구분Shared Schema11tenant_id 컬럼 구조+-------------------+| 클라이언트 요청 ||----------------..

BACKEND 2025.08.21

[DB]차집합 (LEFT OUTER JOIN + IS NULL)

차집합 :A - B : A에 있지만 B에는 없는 데이터 Oracle / MSSQL에서는 MINUS나 EXCEPT를 사용하면 쉽게 구현 가능: -- OracleSELECT ID FROM TB1MINUSSELECT ID FROM TB2;-- MSSQLSELECT ID FROM TB1EXCEPTSELECT ID FROM TB2;MySQL에서는 MINUS / EXCEPT가 없음MySQL 8.0 이상에서 EXCEPT가 지원되지만, 이전 버전에서는 지원되지 않음대신 LEFT JOIN + IS NULL 패턴으로 차집합을 구현할 수 있음-- mysqlSELECT *FROM TB1 aLEFT OUTER JOIN TB2 bON a.ID = b.IDWHERE b.ID IS NULL;설명LEFT OUTER JOIN TB2..

BACKEND 2025.08.19

[MyBatis] flushStatements

실무 [트러블슈팅 노트] RESTAPI 테스트를하는중 기존의 환경에서 보낸 결과 반환 값과 내 작업 결과 반환값이 달라 코드를 분석하였다. flushStatements 가 문제 였는데 flushStatements 1️⃣ 기본 개념flushStatements()는 MyBatis의 SqlSession에서 실행 대기 중인 SQL 문(statement)을 DB에 보내고, 그 결과를 반환하는 메서드입니다.MyBatis는 기본적으로 **배치 모드(batch mode)**를 지원합니다.배치 모드에서는 insert, update, delete 같은 DML 문이 모아서 한 번에 DB로 보내집니다.이때 아직 DB에 보내지 않은 SQL들을 즉시 실행하고 싶은 경우 flushStatements()를 사용합니다.SqlSess..

BACKEND 2025.08.14

[DB] 옵티마이저 힌트(Optimizer Hint)

실무 [트러블슈팅] Optimizer Hint 옵티마이저 힌트(Optimizer Hint)**는 SQL 실행 계획을 개발자가 직접 제어하기 위해 SQL 안에 넣는 지시문입니다.SELECT /*+ HINT_NAME(parameters) */ col1, col2FROM table1 t1, table2 t2WHERE t1.id = t2.id;/*+ ... */ 형태로 SQL 바로 뒤에 작성대문자 사용 권장힌트는 SQL 구문과 동일한 순서에 적용1️⃣ 자주 사용하는 힌트 종류 힌트 설명 FULL(table)테이블 전체 스캔 사용INDEX(table index_name)특정 인덱스 사용LEADING(table1 table2)조인 순서 지정USE_NL(table)Nested Loop Join 강제USE_HAS..

BACKEND 2025.08.14