[Spring] Docker MySQL JDBC 연결

dondonee·2023년 11월 25일

Docker MySQL JDBC 연결하기

1. Docker MySQL 컨테이너 생성

(1) 컨테이너 설정 파일 작성

도커 설정 파일을 생성한다. 보통 프로젝트 루트 폴더에 생성한다. 파일명은 compose 또는 docker-compose, 확장자명은 .yaml 또는 .yml 모두 가능하다.

version: '3'

services:
  db:
    image: mysql:8.0
    container_name: board-mysql
    restart: always
    ports:
      - 3306:3306
    environment:
      MYSQL_ROOT_PASSWORD: "root1234"
      MYSQL_DATABASE: "mydb"
      MYSQL_USER: "me"
      MYSQL_PASSWORD: "me1234"
    command:
      - --character-set-server=utf8mb4
      - --collation-server=utf8mb4_unicode_ci
    volumes:
      - ./database/datadir/:/var/lib/mysql
      - ./database/init/:/docker_entrypoint-initdb.d/
  • version(선택) : compose 파일의 버전을 명시. 기능을 하지는 않음.
  • image : 사용할 도커 이미지
    • MySQLWorkbench(8.0.34)가 MySQL 8.0까지만 지원해서 8.0 사용
  • ports : 포트 포워딩
    • 도커 컨테이너는 가상 IP 주소를 사용하기 때문에 호스트 포트로 요청이 들어오면 컨테이너 포트로 포워딩이 필요하다(3306->3306).

(2) 컨테이너 생성

설정 파일이 위치한 경로에서 다음 명령어를 실행해 컨테이너를 생성한다.

$ docker-compose up

컨테이너 생성이 완료되었다. 생성 후 프롬프트가 사라져서 이어서 명령을 할 수가 없고 ctrl + C를 하면 컨테이너가 종료된다 ... 이유는 잘 모르겠다 ^^ 나는 그냥 컨테이너를 재시작 하거나 새 터미널 창을 켜서 작업하고 있다 😅


(3) 완료

$ docker ps
CONTAINER ID   IMAGE       COMMAND                   CREATED              STATUS              PORTS                               NAMES
bd205b5672e1   mysql:8.0   "docker-entrypoint.s…"   About a minute ago   Up About a minute   0.0.0.0:3306->3306/tcp, 33060/tcp   board-mysql

도커 데스크탑에서 생성된 컨테이너를 확인할 수 있다. 컨테이너 이름이 mysql로 나오지만 CLI에서 docker ps 명령으로 실행 중인 컨테이너 목록을 확인해보면 컨테이너 이름이 설정한 대로 board-mysql로 잘 생성되어 있다.


+) 설정 변경해서 컨테이너를 새로생성하고 싶을 때

도커 데스크탑에서 컨테이너를 삭제하고 설정 파일을 수정한 뒤 다시 docker-compose up을 했는데 변경 내용이 적용이 안됐다. 몇 번을 재시도해도 똑같았다.

컨테이너를 처음 생성하면 프로젝트 루트에 database 디렉토리가 생기는데 이걸 삭제해주어야 한다. 디렉토리 삭제 후 다시 docker-compose up을 하면 설정 변경이 잘 적용되어 새삥 컨테이너가 생성된다. 😀



2. MySQL 접속

개발 도중에 데이터베이스의 스키마나 데이터를 확인해야 할 때가 많다. CLI에서 MySQL에 직접 접근할 수도 있고 MySQLWorkbench와 같은 GUI 프로그램을 통해서 예쁘게 정리된 화면에서 DB를 조작할 수도 있다.

CLI는 배우기 어렵지만 GUI 프로그램에 비해 훨씬 가볍고 DB 연결이 더 안정적이다. 나도 처음에는 왜 굳이 어렵게 CLI를 배워야 할까 싶었는데, 지금은 간단한 확인은 CLI로 하는 것을 선호하게 되었다. 오히려 프로그램이 복잡할수록 CLI가 선호될 때도 있다고 하니 더 익숙해져야 될 것 같다.

a. CLI로 접속하기

(1) 컨테이너 시작

도커 이미지로 띄운 MySQL이기 때문에 먼저 도커로 들어가야 MySQL에 접속할 수 있다.

  • docker ps -a를 실행하면 모든 컨테이너의 목록을 확인할 수 있다(중단된 컨테이너 포함).
  • docker start board-mysql : board-mysql 컨테이너를 실행한다.
    • 도커 데스크탑에서 시작 버튼(▶️)을 눌러도 된다.
  • 도커 CLI가 없고 데스크탑만 있다면 데스크탑을 켜 놓아야 docker 명령어를 사용할 수 있다.

(2) 컨테이너 실행

$ docker exec -it board-mysql bash
bash-4.4#

터미널을 통한 컨테이너 조작을 시작하기 위한 명령어이다. 컨테이너 외부에서 board-mysql이라는 컨테이너의 bash를 -it 옵션으로 실행시킨다.

  • docker exec 명령은 컨테이너 외부에서 컨테이너를 실행하는 명령어이다.
  • bash 실행시에는 대부분 -it 옵션을 사용한다.
    • -i(--interactive) : 표준 입력을 사용
    • -t(--tty) : 가상 터미널 환경에서 입출력을 사용

정상 실행되면 bash 프롬프트(bash-4.4#)가 나타나고, 컨테이너에 셸 명령어를 사용할 수 있다.


(2) MySQL 접속

bash-4.4# mysql -u root -p
  • MySQL 접속 시에는 root 사용자로 접근해야 함.
    • 패스워드 : root1234 (MYSQL_ROOT_PASSWORD)
    • 컨테이너 생성할 때 만들었던 me 사용자로 접근하면 오류 발생 :
      ERROR 1045 (28000): Access denied for user 'me'@'localhost' (using password: YES)

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| mydb               |
| information_schema |
| mysql              |
| performance_schema |
| sys                |
+--------------------+

show databases를 통해 데이터베이스 목록을 확인해보자. 기본 생성된 데이터베이스들이 있고, 내가 설정 파일을 통해 만든 mydb 데이터베이스가 있다

  • mydb : 도커 초기화 파일에서 내가 만든 데이터베이스 (스프링에 연결해서 사용할 DB)
  • mydb 사용하기 : use mydb

스프링 프로젝트에 매핑할 데이터베이스 스키마를 만들기 위해서는 use mydb를 통해 사용할 데이터베이스를 선택한 뒤 작업하면 된다.


b. GUI로 접속하기

MySQLWorkbench는 MySQL 공식 GUI 프로그램이다. CLI보다 연결과 조작이 간편하다. (근데 맥 M2에서는 자주 튕긴다...ㅎㅎ)

  • 커넥션 Name : 커넥션을 구분하기 위한 이름. 자유롭게 작성.
  • HostName : 서버 호스트 IP와 포트 번호
  • Username : 연결할 사용자
  • Password : 사용자의 비밀번호, me1234(MYSQL_PASSWORD)
  • Default Schema : 기본으로 사용할 DB, mydb

"Succesfully made the MySQL connection" 안내가 뜨면 성공적으로 연결이 된 것이다.



3. Spring 연결

(1) 연결 설정

스프링 부트에 데이터베이스 의존성을 추가했다면 스프링은 프로젝트를 자동 빌드하면서 연결할 DB의 datasource를 찾는다. 스프링이 연결할 DB의 위치와 정보를 알 수 있도록 애플리케이션 설정 파일 application.yml에 다음과 같이 DB datasource에 대한 정보를 지정해주어야 한다.

//build.gradle
implementation 'org.springframework.boot:spring-boot-starter-jdbc'
spring:
  datasource:
    url: jdbc:mysql://127.0.0.1:3306/mydb?useUnicode=true&serverTimezone=Asia/Seoul
    username: me
    password: me1234
  • url :
    • jdbc:mysql:// : JDBC가 MySQL에 연결하기 위한 프로토콜
    • 127.0.0.1:3306 : MySQL 서버의 호스트와 포트
    • username, password : 연결할 사용자 정보

(2) 테스트

@SpringBootTest
@Transactional
class BoardApplicationTest {

    @Autowired
    JdbcTemplate jdbcTemplate;

    @Test
    public void testJdbcConnection() {
        //given
        jdbcTemplate.execute("CREATE TABLE IF NOT EXISTS test_table (id INT, name VARCHAR(255))");
        jdbcTemplate.update("INSERT INTO test_table VALUES (1, 'Kim')");

        //when
        String result = jdbcTemplate.queryForObject("SELECT name FROM test_table WHERE id = 1", String.class);

        //then
        assertTrue("Kim".equals(result));
    }

}

JDBC를 통해 테이블을 생성하고 데이터를 삽입한 뒤, 데이터를 조회해본다. 테스트를 통과하면 DB 연결이 끝난 것이다!!




🔗 Reference

0개의 댓글