Java프로그래밍

Java ↔ DB byte 길이 맞추는 방법

실무에서 많이 터지는 포인트라 제대로 맞춰야 합니다. 핵심은 Java와 PostgreSQL이 “같은 기준(인코딩 + 계산 방식)”을 쓰게 만드는 것


1. 기준 통일 (가장 중요) : 반드시 UTF-8 기준으로 통일

  • PostgreSQL: 기본 UTF8
  • Java: StandardCharsets.UTF_8
SHOW server_encoding;
-- UTF8 이어야 정상
str.getBytes(StandardCharsets.UTF_8)

2. Java ↔ PostgreSQL 매칭 공식

JavaPostgreSQL
str.getBytes(UTF_8).lengthOCTET_LENGTH(col)

👉 완전히 동일하게 동작함


3. Java byte 길이 함수 (공통)

import java.nio.charset.StandardCharsets;public class ByteUtil {    public static int getByteLength(String str) {
if (str == null) return 0;
return str.getBytes(StandardCharsets.UTF_8).length;
}
}

4. Java에서 byte 기준 truncate (DB랑 동일하게)

public static String truncateByByte(String str, int maxBytes) {
if (str == null) return null; StringBuilder sb = new StringBuilder();
int byteCount = 0; for (char c : str.toCharArray()) {
int charBytes = String.valueOf(c).getBytes(StandardCharsets.UTF_8).length; if (byteCount + charBytes > maxBytes) {
break;
} sb.append(c);
byteCount += charBytes;
} return sb.toString();
}

5. DB와 완벽 비교 검증

String data = "한글ABC123";// Java
int javaBytes = ByteUtil.getByteLength(data);// DB
SELECT OCTET_LENGTH('한글ABC123');

👉 결과 동일해야 정상


6. 실무 적용 패턴 (추천 )

✔ 서비스단 (1차 방어)

if (getByteLength(msg) > 2000) {
msg = truncateByByte(msg, 2000);
}

✔ DB (2차 방어)

  • trigger 또는 constraint

👉 이렇게 이중 방어 구조가 정석


실무에서 진짜 중요한 함정들

1. VARCHAR(n) 착각

  • VARCHAR(100) = 문자 100개 (byte 아님)
  • 👉 byte 제한은 별도 체크 필요

2. 이모지 문제

😀 = 4byte (UTF-8)

👉 Java / PostgreSQL 동일하게 처리됨 (UTF-8이면 OK)


3. substring 쓰면 깨짐

str.substring(0, 10) ❌ (byte 기준 아님)

7. 추천 구조 (실무 베스트)

[Java]
- byte 체크 + truncate[DB]
- OCTET_LENGTH 체크 or 트리거=> 데이터 100% 안전

결론

  • Java = getBytes(UTF-8).length
  • PostgreSQL = OCTET_LENGTH()
  • 둘은 완전히 동일 기준

나중에 또 추가할 내용

  • LMS 자동 분기 (SMS/LMS 나누기 로직)
  • byte 기준 마스킹
  • 대용량 처리 최적화 버전 (성능 개선)
Hi, I’m 관리자