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 매칭 공식
| Java | PostgreSQL |
|---|---|
str.getBytes(UTF_8).length | OCTET_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 기준 마스킹
- 대용량 처리 최적화 버전 (성능 개선)



