Java 8부터 도입된 null을 안전하게 처리하기 위한 래퍼 클래스
String name = person.getName(); // name이 null 이면 NPE 발생
-> NullPointerException(NPE) 발생 가능성이 존재
java.util.Optional<T> 형태로 사용되며, null 값을 직접 다루지 않고도 값이 존재할 수도 있고 없을 수도 있는 상황을 처리할 수 있도록 도와준다.
| 메서드 | 설명 |
|---|---|
Optional.of(value) | 절대 null이 아닌 값을 감쌈 (null이면 예외 발생) |
Optional.ofNullable(value) | null일 수도 있는 값을 감쌈 |
Optional.empty() | 빈 Optional 객체 생성 |
isPresent() | 값이 존재하면 true |
ifPresent(Consumer) | 값이 존재할 때 동작 실행 |
get() | 값 반환 (값이 없으면 예외 발생) |
orElse(defaultValue) | 값이 없으면 기본값 반환 |
orElseGet(Supplier) | 값이 없으면 함수형 인터페이스로 기본값 생성 |
orElseThrow(Supplier) | 값이 없으면 예외 발생 |
Optional<String> name = Optional.of("John");
System.out.println(name.get()); // John
Optional<String> empty = Optional.empty();
System.out.println(empty.orElse("default")); // default
Optional<String> maybeNull = Optional.ofNullable(null);
maybeNull.ifPresent(System.out::println); // 실행 안 됨
String result = maybeNull.orElseGet(() -> "Generated");
System.out.println(result); // Generated
| 항목 | MyBatis | JPA |
|---|---|---|
| 데이터 객체 | VO (모든 계층에서 동일) | Entity, DTO 분리 |
| SQL 처리 방식 | XML Mapper 사용 | ORM 기반 자동 쿼리 |
| 구조 단순성 | 단순하지만 불안정 | 구조화되어 보안/유지보수 유리 |
| 계층 간 분리 | 없음 | 명확히 분리 (프론트와 도메인 영역) |
| 대표 단점 | 보안에 취약 (비밀번호 전달 등), 계층 혼재 | 학습 곡선 있음, 추상화로 인한 디버깅 어려움 |
Controller -> Service -> DAO -> VO -> Mapper(XML) -> DB
Controller -> Service -> DTO -> Repository -> Entity -> DB
스프링 프레임워크를 더 쉽고 빠르게 사용할 수 있도록 도와주는 도구(프레임워크)
기존 Spring Framework는 유연하지만, 설정 파일(XML)이 많고, 초기 환경 구성에 시간이 오래 걸리고, 실행하려면 외부 Tomcat 서버가 필요하다.
Spring Boot는 복잡한 설정을 최소화하고, 빠르게 애플리케이션을 개발,배포할 수 있도록 도와준다.
application.properties 또는 application.yml만 설정해도 동작한다.spring-boot-start-web, spring-boot-starter-data-jpa 등Spring Boot Actuator 지원@SpringBootApplication // @Configuration + @EnableAutoConfiguration + @ComponentScan
public class MyApp {
public static void main(String[] args) {
SpringApplication.run(MyApp.class, args); // 내장 서버 실행
}
}
@SpringBootApplication : 스프링 부트의 핵심 어노테이션. 설정과 컴포넌트 스캔 등을 포함
SpringApplication.run(...) : 내장 서버(Tomcat 등)를 실행하여 애플리케이션 구동
| Starter | 설명 |
|---|---|
spring-boot-starter-web | 웹 애플리케이션 (MVC 포함) |
spring-boot-starter-data-jpa | JPA 사용을 위한 기본 설정 |
spring-boot-starter-security | 보안 설정 (로그인/인가 등) |
spring-boot-starter-test | 테스트 관련 라이브러리 (JUnit, Mockito 등) |
spring-boot-starter-thymeleaf | 템플릿 엔진 Thymeleaf 사용 |
웹 애플리케이션 개발에 필요한 필수 라이브러리들을 묶어놓은 Starter
| 라이브러리 | 설명 |
|---|---|
| Spring MVC | 웹 애플리케이션 구조 (Controller, RestController 등) |
| Jackson | JSON 변환 (Java ↔ JSON 자동 매핑) |
| Validation (spring-boot-starter-validation) | 입력값 검증 (@Valid, @NotNull 등) |
| Tomcat (내장) | 내장 웹 서버 (별도 설치 없이 실행 가능) |
| 항목 | Spring Framework | Spring Boot |
|---|---|---|
| 설정 방식 | XML 또는 자바 설정 클래스 필요 | 자동 설정 + 최소한의 설정 |
| 서버 배포 | WAR 파일을 만들어 WAS에 배포 | 내장 톰캣으로 JAR 실행 가능 (java -jar) |
| 시작 속도 | 복잡하고 설정이 많음 | 빠르게 시작 가능 (개발 친화적) |
| 구조 설계 | 개발자가 일일이 설정 | 대부분 자동으로 구성됨 |
자바에서 반복되는 코드(보일러플레이트, boilerplate)를 자동으로 생성해주는 라이브러리
다양한 어노테이션을 통해 코드 간결성, 생산성, 가독성을 높여준다.
| 어노테이션 | 설명 |
|---|---|
@Getter, @Setter | 필드에 대해 getter, setter 자동 생성 |
@ToString | toString() 메서드 자동 생성 |
@EqualsAndHashCode | equals(), hashCode() 자동 생성 |
@NoArgsConstructor | 파라미터 없는 생성자 자동 생성 |
@AllArgsConstructor | 모든 필드를 파라미터로 받는 생성자 생성 |
@RequiredArgsConstructor | final 또는 @NonNull 필드만 포함한 생성자 생성 |
@Data | @Getter, @Setter, @ToString, @EqualsAndHashCode, @RequiredArgsConstructor 조합 |
@Builder | 빌더 패턴 지원 (체이닝 방식 생성자) |
@Slf4j | 로그 객체 log 자동 생성 (log.info() 등 사용 가능) |
dependencies {
compileOnly 'org.projectlombok:lombok:1.18.30' // 최신 버전 확인
annotationProcessor 'org.projectlombok:lombok:1.18.30'
}
Java에서 열거형(Enumeration)을 정의할 때 사용하는 특수한 클래스
미리 정의된 상수들의 집합을 만들귀 위한 클래스이다.
ex) 요일, 상태값, 등급 등
public enum Day {
MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
}
// 사용법
// Day.MONDAY
== 연산자로 비교 가능 (주소 비교 OK)
// 필드와 메소드 가진 enum
public enum Grade {
BASIC(0),
SILVER(1),
GOLD(2);
private final int level;
// 생성자
Grade(int level) {
this.level = level;
}
public int getLevel() {
return level;
}
}
Grade g = Grade.GOLD;
System.out.println(g); // GOLD
System.out.println(g.getLevel()); // 2
switch (g) {
case BASIC:
System.out.println("기본 회원");
break;
case GOLD:
System.out.println("골드 회원");
break;
}
DAO 역할을 하는 Repository 인터페이스 설계
JpaRepository 또는 CrudRepository를 상속받아 데이터 접근 기능을 갖는 인터페이스를 정의한다.
첫 번째 제네릭에 엔티티 클래스,
두 번째 제네릭에 기본키 타입을 넣어
데이터 접근 기능을 설계한다.
@Entity
public class User {
@Id
private Long id;
private String name;
// ... 기타 필드
}
public interface UserRepository extends JpaRepository<User, Long> {
// 기본적인 CRUD 메서드는 자동 생성됨
// 추가로 사용자 정의 메서드 작성 가능
}
| 위치 | 제네릭 타입 | 의미 |
|---|---|---|
| 첫 번째 | User | 엔티티 클래스 이름 (DB 테이블과 매핑되는 클래스) |
| 두 번째 | Long | 기본키(PK)의 타입 (@Id에 해당하는 필드 타입) |
구현 클래스 없이 인터페이스만 작성해도 동작한다.
Spring이 런타임에 자동으로 구현체를 생성해주기 때문
자바에서
Proxy클래스를 사용하면 인터페이스 기반으로 런타임에 클래스 없이 객체를 생성할 수 있다.
이 기능을 활용하여 Spring은 인터페이스에 대한 구현체를 자동으로 생성한다.
UserRepository repo = new 프록시_객체();
repo.findByUsername("kim"); // -> 내부적으로 쿼리 생성해서 DB 호출

오늘은 스프링 부트와 JPA에 대해 공부했다.
스프링 부트는 복잡한 설정 없이 빠르게 웹 애플리케이션을 시작할 수 있게 해주며, 내장 톰캣과 자동 설정 기능이 있다. JPA는 객체와 테이블을 매핑하여 SQL 없이도 데이터베이스를 다룰 수 있게 해주고, 생산성과 유지보수성을 높여준다. 특히 Spring Data JPA는 Repository 인터페이스만 정의하면 동적 프록시로 구현체를 자동 생성해주는 점이 편리했다. 쿼리 메서드나 @Query를 통해 다양한 방식으로 쿼리를 작성할 수 있는 것도 유용했다.
전체적으로 반복되는 코드가 줄고 구조가 깔끔해져 실무에 유용하겠다는 생각이 들었다.