본문 바로가기
Blog/TIL

2025-03-07 (금)

by 코젼 2025. 3. 7.
728x90
반응형

🚀 최종 정리

✅ Serializable → JPA에서 복합 키 사용 시 필수

✅ @EmbeddedId + @Embeddable → MySQL 복합 키 설정 시 권장 방식

✅ require → 매개변수 검증을 간결하게 처리할 때 사용

✅ Set<T>?.orEmpty() → null 방지 및 안정적인 코드 작성 가능

✅ optimizeReadOnlySet() → 메모리 최적화를 위해 사용

✅ first() vs any() → 첫 번째 요소 조회 vs 요소 존재 여부 확인

1. Serializable (직렬화)

  • Serializable은 객체를 바이트 스트림으로 변환하여 저장하거나 네트워크로 전송할 때 사용된다.
  • JPA에서 @EmbeddedId 또는 @IdClass를 사용할 때, 복합 키 클래스는 반드시 Serializable을 구현해야 한다.
  • 이를 통해 JPA가 객체를 PK로 인식하고 비교하거나 캐시할 때 오류 없이 처리할 수 있다.

📌 사용 예제

import java.io.Serializable

data class User(
    val id: String,
    val name: String
) : Serializable

2. MySQL 복합 키 설정

📌 @EmbeddedId + @Embeddable + Serializable

  • 복합 키(Composite Key)를 사용할 때 권장되는 방법
  • @EmbeddedId를 사용하면 객체지향적으로 복합 키를 관리할 수 있어 가독성이 좋다.

📌 예제 코드

import jakarta.persistence.*
import java.io.Serializable

@Embeddable
data class Entity(
    val aId: String,
    val bId: String
) : Serializable

@Entity
@Table(name = "Entity2")
class AAA(
    @EmbeddedId
    val aaa: AAA
)

  • @Embeddable 클래스에서 Serializable을 구현해야 한다.
  • @EmbeddedId를 사용하여 복합 키를 Entity에 포함할 수 있다.

3. Kotlin require

  • require(condition) { "에러 메시지" }는 함수의 매개변수를 검증할 때 사용한다.
  • 조건이 충족되지 않으면 IllegalArgumentException을 발생시킨다.

📌 예제 코드

fun setAge(age: Int) {
    require(age > 0) { "나이는 0보다 커야 합니다: $age" }
    println("나이 설정 완료: $age")
}

setAge(25)  // ✅ 정상 실행
setAge(-1)  // ❌ 예외 발생

  • require를 활용하면 입력값 검증을 간결하게 처리할 수 있다.
  • 가독성이 높고 if문보다 코드가 직관적이다.

4. Set<T>?.orEmpty() & optimizeReadOnlySet()

📌 orEmpty()

  • null인 Set을 빈 Set으로 변환하여 NPE(NullPointerException)를 방지한다.
val nullableSet: Set<String>? = null
val nonNullableSet = nullableSet.orEmpty() // 빈 Set 반환

println(nonNullableSet) // 출력: []

📌 optimizeReadOnlySet()

  • 읽기 전용 Set을 최적화하여 불필요한 메모리 사용을 방지한다.

📌 예제 코드

internal fun <T> Set<T>.optimizeReadOnlySet() = when (size) {
    0 -> emptySet()  // ✅ 크기가 0이면 싱글톤 빈 Set 사용
    1 -> setOf(iterator().next())  // ✅ 크기가 1이면 단일 원소 Set으로 최적화
    else -> this
}

  • emptySet()을 활용하여 불필요한 객체 생성을 막는다.
  • size == 1이면 단일 원소 Set을 생성하여 메모리 사용을 줄인다.

5. first() vs any() 차이

함수 역할 반환 값 예외 발생 여부

first() 첫 번째 요소 반환 또는 조건을 만족하는 첫 번째 요소 반환 첫 번째 요소 요소가 없으면 예외 발생 (NoSuchElementException)
any() 컬렉션이 비어있는지 확인 또는 특정 조건을 만족하는 요소가 하나라도 있는지 확인 true 또는 false 예외 발생하지 않음

📌 예제 코드

val numbers = listOf(1, 2, 3, 4, 5)

// ✅ first() 사용 (조건 만족하는 첫 번째 요소 반환)
val firstEven = numbers.first { it % 2 == 0 }
println(firstEven) // 출력: 2

// ✅ any() 사용 (조건을 만족하는 요소가 있는지 확인)
val hasEven = numbers.any { it % 2 == 0 }
println(hasEven) // 출력: true

  • first()는 조건을 만족하는 첫 번째 요소를 반환하지만, 요소가 없으면 예외 발생
  • any()는 조건을 만족하는 요소가 하나라도 있으면 true, 없으면 false 반환
728x90
반응형

'Blog > TIL' 카테고리의 다른 글

2025-03-11 (화)  (1) 2025.03.11
2025-03-10 (월)  (1) 2025.03.10
2025-03-06 (목)  (0) 2025.03.06
2025-03-05 (수)  (0) 2025.03.05
2025-03-04 (화)  (0) 2025.03.04

댓글