MySQL 연결 - characterEncoding=utf8mb4 쓰지 마세요!

2024. 12. 12. 14:28·백엔드

요약

utf8mb4로 인코딩된 데이터에 접근하고자 할 때,

 

jdbc:mysql://{db주소}?useUnicode=true&characterEncoding=utf8mb4

대신

jdbc:mysql://{db주소}?useUnicode=true&character_set_server=utf8mb4

 쓰세요!

 

또는,

이미 DB서버의 my.cnf 파일을 character_set_server=utf8mb4로 설정했다면

jdbc:mysql://{db주소}?useUnicode=true

또는

jdbc:mysql://{db주소}?useUnicode=true&characterEncoding=utf8

로 접근하세요!

 

+ Java 인코딩 - MySQL 인코딩 매핑 테이블 

 


배경

백엔드 -> DB서버에 접속하도록 설정했다.

 

특히 application.yml 속

spring.datasource.url 을 통해 DB에 어떻게 접근할지 명명하는 부분에서,

characterEncoding=utf8mb4 옵션으로 인코딩 방식을 사용했다

 

# application.yml (에러)

spring:
  datasource:
    url: jdbc:mysql://{db연결주소}:3306/{db명}?useUnicode=true&characterEncoding=utf8mb4

에러

하지만 방금과 같이 characterEncoding=utf8mb4로 설정한다면 다음과 같이 에러를 내뱉으며 

springboot 백엔드 서버가 실행되지 않는다.

Caused by: com.mysql.cj.exceptions.WrongArgumentException: Unsupported character encoding 'utf8mb4'

응 ?? utf8mb4를 지원하지 않는다고 한다. 

 

하지만,

지난 시간의 수작업을 통해 

나는 분명 MySQL 인코딩 방식을 utf8mb4로 변경했다.

 

MySQL에 접속해봐도 인코딩 방식이 utf8mb4인 것을 확인할 수 있다......

MySQL은 utf8mb4 인코딩이다..

 


해결

의아한 채로 우선 구글링을 시도했다.

다행히 블로그에 잘 나와있었는데,

https://indienote.tistory.com/664

 

MySQL - Unsupported character encoding 'utf8mb4'

MySQL 접속에서 (나의경우 MyBatis) 다음과 같은 경우의 에러가 발생하였다. Unsupported character encoding 'utf8mb4' 다음과 같은 연결을 사용하고 있었다. jdbc.url=jdbc:mysql://localhost:3306/dbname?useSSL=false&serverTimez

indienote.tistory.com

 

이 글에 따르면 

characterEncoding=utf8mb4 대신 

character_set_server=utf8mb4로 수정해 해결했다고 한다!

 

 

나또한 반신반의한 마음으로 적용한 결과,

# application.yml (수정 후)

spring:
  datasource:
    url: jdbc:mysql://{db연결주소}:3306/{db명}?useUnicode=true&character_set_server=utf8mb4

(application.yml 파일 속 DB url 부분을 수정했다)

뿅! 실행되었다!

어라?

잘 실행되는 모습을 볼 수 있었다...


왜 에러가 발생한 것인가? (관련 용어 정리)

왜 해결된거지? (왜 돌아가지..?)

를 이해하기 위해 좀더 알아보기로 하자.

 

우선

characterEncoding=utf8mb4 옵션이 뭘 나타내는지 알아보자

 

1. characterEncoding=utf8mb4 옵션

✔️ 클라이언트 ➔ 서버로 데이터 보낼 때의 인코딩 방식 결정

✔️ Connector/J의 연결 속성 중 하나 

 

Connector/J란?

MySQL 서버와 통신하기 위한 JDBC API & MySQL DevAPI를 구현한 드라이버

https://dev.mysql.com/doc/connector-j/en/

 

Connector/J의 연결 속성

[공식문서] Connector/J의 연결 속성

 

 

2. character_set_server=utf8mb4 옵션

✔️ 서버의 인코딩 방식 지정하는 시스템 변수

 

DB에 어떤 인코딩 방식으로 데이터를 저장할지 명시하는 부분

 

 

3. server vs client 인코딩

정리하자면,

characterEncoding은

클라이언트인 Java 어플리케이션 -> DB 서버로 전송할 때의 데이터 인코딩 방식을 의미하고

 

character_set_server는

DB 서버에서 데이터를 어떻게 저장할것인가? 에 대한 인코딩 방식인 것이다!

 

 

 

(참고) 4. characterEncoding 없을 때는?


✔️ Connector/J 8.0.25 (포함) 이전

characterEncoding 또는 connectionCollation 명시 x

➔ my.cnf 파일 (MySQL 서버 설정 파일)에 정의된 character_set_server 값 사용

 

✔️ Connector/J 8.0.26 (포함) 이후

characterEncoding 또는 connectionCollation 명시 x

➔ 기본적으로 utf8mb4 문자 집합 사용

 

공식문서 참고 

 


왜 에러가 발생한 것인가?

그럼 이제 진짜 왜 에러가 발생한건지 알아보자.

 

지난 시간의 설정을 통해,

DB의 character_set_server=utf8mb4로 설정했다.

 

characterEncoding은 자바 어플리케이션에서 DB서버로 보내는 인코딩 양식이라 했다!

그렇다면 Java에서 utf8mb4를 지원하는지를 확인하자!

 

1. Java에서 지원하는 Charset 확인

// Application.java

import java.nio.charset.Charset;
import java.util.Map;

@EnableJpaAuditing
@SpringBootApplication
public class BusinessCardApplication {

	public static void main(String[] args) {
		Map<String, Charset> charsets = Charset.availableCharsets(); // 추가
		for (String name : charsets.keySet()) { // 추가
			System.out.println(name); // 추가
		}
		SpringApplication.run(BusinessCardApplication.class, args);
	}

}

 

charset 확인 부분을 추가하자!

utf8mb4가 없다

 

이어서 application을 실행하니, 

Java에서 utf8mb4를 지원하지 않는것을 볼 수 있다!

 

 

즉, 나는 client인 Java Application에서 지원하지 않는 인코딩 방식(utf8mb4)를 사용해 에러가 난 것이다!!

 

해결 방법은 2가지가 있을 것이다.

1. jdbc:mysql://{db주소}?useUnicode=true 로 접근

명시하지 않는 경우, 

Connector/J 8.0.26 이전/이후든 서버의 utf8mb4에 맞는 인코딩 방식을 설정할 것이므로 해결될 것이다.

 

하지만 이참에 Connector/J의 버전도 알아보자!

 

build.gradle

// build.gradle

dependencies {
	// ... 생략
	implementation 'com.mysql:mysql-connector-j'
}

헉 버전이 나와있지 않다

 

이런 경우, 

./gradlew dependencies

명령어를 프로젝트 폴더에서 실행하면 

의존성 resolve 결과를 알 수 있다고 한다.

(이 작업을 통해 실제 정확한 버전의 라이브러리, 의존성을 다운로드한다고 한다!)

찾았다! 8.3.0

그렇다!

나는 Connector/J 8.0.26 이후 버전이므로,

characterEncoding을 명시하지 않았을 경우 기본적으로 utf8mb4에 맞는 인코딩으로 

Java application -> DB 서버로 연결을 시도하는 것이다!

 

 

2. jdbc:mysql://{db주소}?useUnicode=true&characterEncoding=utf8 로 접근

이번에는 명시적으로 Java Application -> DB 서버로의 인코딩 방식을 적어주자!

 

잠깐!

Java - MySQL 간 어떤 인코딩 방식이 매핑되어있는지 어떻게 알지?

공식문서를 보면 된다! 

https://dev.mysql.com/doc/connector-j/en/connector-j-reference-charsets.html

 

MySQL :: MySQL Connector/J Developer Guide :: 6.7 Using Character Sets and Unicode

6.7 Using Character Sets and Unicode All strings sent from the JDBC driver to the server are converted automatically from native Java Unicode form to the connection's character encoding, including all queries sent using Statement.execute(), Statement.exec

dev.mysql.com

 

 

이 매핑 테이블을 보면 (마지막 2번째)

utf8mb4에 매핑되는 Java의 인코딩 방식은 UTF-8 이다!

 

즉, 

characterEncoding=utf8 

로 Java Application -> DB 서버로 접속하면 되는 것이다!


여담

먼 길 돌아왔다..

 

인코딩이라고 하면 단순히 DB 저장 인코딩만 생각했는데,

자바 Application -> DB 로의 데이터 전송 인코딩도 있었다니!  (신기하다)

 

또,

의존성 resolve 방식을 찾는 명령어

./gradlew dependencies

를 통해, 라이브러리의 실제 버전을 찾는것도 유용하게 사용할 듯 싶다!


참고

 

공식문서 - 매핑 테이블 https://dev.mysql.com/doc/connector-j/en/connector-j-reference-charsets.html

 

공식문서 - characterEncoding https://dev.mysql.com/doc/connector-j/en/connector-j-connp-props-session.html#cj-conn-prop_characterEncoding

 

같은 에러를 겪은 블로그 - https://indienote.tistory.com/664

'백엔드' 카테고리의 다른 글

[스프링부트] 디스코드 웹훅 (1) - 에러 로그 전송 (logback)  (1) 2025.01.07
[DB 해킹] MySQL DB 털린 썰 풉니다 (RECOVER_YOUR_DATA)  (2) 2024.12.23
[스프링부트] Soft delete 구현  (1) 2024.12.09
[스프링부트] Spring Batch와 적용방법  (3) 2024.12.09
MySQL 한글 (인코딩) 에러 났을 때 해결방법  (0) 2024.12.09
'백엔드' 카테고리의 다른 글
  • [스프링부트] 디스코드 웹훅 (1) - 에러 로그 전송 (logback)
  • [DB 해킹] MySQL DB 털린 썰 풉니다 (RECOVER_YOUR_DATA)
  • [스프링부트] Soft delete 구현
  • [스프링부트] Spring Batch와 적용방법
KyuminKim
KyuminKim
컴퓨터공학과 학생의 이모저모 개발 일지 📝
  • KyuminKim
    이모저모
    KyuminKim
  • 전체
    오늘
    어제
    • 분류 전체보기 (53)
      • 프로젝트 (2)
        • first-blog (2)
      • 클라우드 (22)
        • 도커 (14)
        • 쿠버네티스 (5)
        • AWS (2)
      • 알고리즘 (5)
        • 코드트리 (0)
        • 프로그래머스 (5)
      • 백엔드 (8)
      • 프론트엔드 (2)
      • 보안 (3)
        • 드림핵 (2)
      • python (3)
      • 네트워크 (1)
      • 기타 (6)
        • 2025 프로펙트 부트캠프(1차) | 클라우드 엔.. (0)
        • OSSCA | 2024 오픈소스 컨트리뷰션 아카데.. (0)
        • WIK (0)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    알고리즘
    코드트리
    쿠버네티스
    파이썬
    DP
    characterencoding
    EC2
    도커
    apiserver-runtime
    고랭
    주간레포트
    코드트리조별과제
    docker
    MySQL
    오블완
    recover_your_data
    urf8
    코딩테스트
    character_set_server
    amazonlinux
    티스토리챌린지
    인코딩
    도커파일
    자료구조
    2024 당근 테크 밋업
    DB
    코딩트리조별과제
    진단평가
    탈퇴구현
    cannot send an empty message
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.2
KyuminKim
MySQL 연결 - characterEncoding=utf8mb4 쓰지 마세요!
상단으로

티스토리툴바