본문 바로가기
프로젝트/Recipository

[intelliJ, MySQL DB] 22.09.19. intelliJ에 MySQL 연결하기 (feat. 수많은 난관)

by 규글 2022. 9. 19.

intelliJ에 MySQL 연결하기

1. build.gradle에 dependency 추가

	// MySQL connector for java
	implementation 'mysql:mysql-connector-java'
	// JPA
	implementation 'org.springframework.boot:spring-boot-starter-data-jpa'

 

2. application.properties에 내용 추가

# MySQL 설정
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

# DB Source URL
spring.datasource.url=jdbc:mysql://<IP>:<Port>/<DB name>?useSSL=false&useUnicode=true&serverTimezone=Asia/Seoul

#DB Username
spring.datasource.username=<user name>

#DB Password
spring.datasource.password=<password>

#true 설정시 JPA 쿼리문 확인 가능
spring.jpa.show-sql=true

#DDL(Create, Alter, Drop) 정의시 DB의 고유 기능을 사용할 수 있다.
spring.jpa.hibernate.ddl-auto=update

# JPA의 구현체인 Hibernate가 동작하면서 발생한 SQL의 가독성을 높여준다.
spring.jpa.properties.hibernate.format_sql=true

DDL 옵션은 다음의 내용들이 들어갈 수 있다.

  • create : 기존의 table을 삭제하고 새로 생성한다. (drop + create)
  • create-drop : 위 속성에 추가로 application을 종료할 때, 생성했던 DDL을 제거한다. (drop + create + drop)
  • update : DB의 table과 entity mapping data를 비교해서 변경 사항만 수정한다. (table이 없을 때는 create)
  • validate : DB의 table과 entity mapping data를 비교해서 차이가 있으면 경고를 남기고 application을 실행하지 않는다.
  • none : 자동 생성 기능을 사용하지 않는다.

주의할 점 또한 발견할 수 있었다.[각주:1]

  • 운영 장비에서는 절대 crate, create-drop, update 사용하면 안됨
  • 개발 초기 단계는 create 또는 update
  • 테스트 서버는 update 또는 validate
  • 스테이징과 운영 서버는 validate 또는 none

 

연결하고 프로젝트를 run 해서 정상적으로 서버가 실행되면 된다.

 

3. 확인하기

Memo.java

package com.example.recipository.model.entity;

import lombok.*;

import javax.persistence.*;

@ToString
@Getter
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Entity
public class Memo {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY) //MySQL의 AUTO_INCREMENT를 사용
    private Long id;
    @Column(length = 200, nullable = false)
    private String memoText;
}

 테스트를 위한 Memo class이다.

 

MemoRepository.java

package com.example.recipository.repository;

import com.example.recipository.model.entity.Memo;
import org.springframework.data.jpa.repository.JpaRepository;

public interface MemoRepository extends JpaRepository<Memo, Long> {

}

 테스트를 위한 JpaRepository를 extends 한 MemoRepository interface이다.

 

package com.example.recipository.repository;

import com.example.recipository.model.entity.Memo;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.stream.IntStream;

@SpringBootTest
public class MemoTest {
    @Autowired
    MemoRepository memoRepository;

    @Test
    public void test(){
        IntStream.rangeClosed(1, 10).forEach(i -> {
            Memo memo = Memo.builder()
                    .memoText("Sample..." + i)
                    .build();
            //Create!
            memoRepository.save(memo);
        });
    }
}

  이전 두 file을 만들어두고 test를 진행했다.

 

 그래서 볼 수 있는 것은 이와 같은 문구였다. Class로 작성한 대로 table을 만들어준다. 만약 class에 @Table annotation을 붙여서 이름을 정해주면 해당 이름으로 table이 만들어진다.

 

Caused by: java.sql.SQLSyntaxErrorException: Table 'tbl_memo' already exists

 하지만 test가 아닌 server를 실행했을 때는 위와 같은 문구를 보게 되었다. 문제와 의문은 여기에서 시작되었다.

 

4. 문제

 일단 오류 메시지를 보고 tbl_memo table을 지우고 싶었다. 그런데 workbench 어디에서도 tbl_memo 라는 이름의 table을 발견할 수가 없었다. 그리고 등장하는 'InnoDB' 라는 친구는 대체 무엇인가? 마지막으로 필자가 원하는 것은 'recipository' 라는 schema에 연결하는 것인데, 그렇다면 이 'schema'는 또 무엇인가?

 이 InnoDB와 schema에 관한 내용은 다음 게시글에서 다루도록 하고 일단 어떤 방식으로 해결했는지 그 과정을 기록하려고 한다. 이 과정 또한 intelliJ에 MySQL을 연결하는 것이기에 한 게시물에 작성한다.

 

5. 문제 해결 과정

a. DB Browser 띄우기

 우선 DB Browser에 연결한 Database를 띄워보려고 했다. DB Browser tab에서 초록 plus를 누르면 어떤 것에 연결할 지 선택할 수 있었고, 사용하려는 MySQL을 선택했다.

 

 그럼 위와 같은 창을 보게 된다. 다음과 같이 정리할 수 있다.

  • Name : DB Browser에 보일 이름이다.
  • Host : 연결할 host 정보이다. 기본으로 localhost가 작성되어 있다.
  • Port : 연결할 port 정보이다. 기본으로 3306이 작성되어 있다.
  • Database : 연결할 database의 이름인 것 같다. 기본으로 mysql이 작성되어 있다.
  • User / Password : 연결할 MySQL 계정 정보이다.

 해당 내용들을 작성하고 Test Connection을 눌러 왼쪽과 같은 메시지를 확인하면 된다. 하지만 필자는 처음에는 오른쪽 메시지를 확인하게 되었다. 이유는 application.properties에 작성한 DB Source URL 정보에서 찾을 수 있었다.

 

# DB Source URL
spring.datasource.url=jdbc:mysql://<IP>:<Port>/<DB name>?useSSL=false&useUnicode=true&serverTimezone=Asia/Seoul

 다시 해당 내용을 가져와서 확인해보면, ussSSL은 false, useUnicode는 true, serverTimezone은 Asia/Seoul로 작성했었다.

 

 SSL tab에는 이미 비활성화되어 있어서 그냥 두면 되었고, 나머지는 Properties tab에 오른쪽 이미지처럼 작성해주었다. 그리고 다시 Test Connection을 눌러보면 왼쪽 메시지를 확인할 수 있을 것이다.

 

 연결을 위해 방법을 검색하던 중 발견한 참고할 만한 블로그를 기록해두려고 한다.[각주:2]

 해당 블로그에서는 DB에 연결하는 모든 client에서 위와 같은 설정을 넣어주는 것이 비효율적이라고 언급한다. 그리고 직접 MySQL에서 time-zone 정보를 수정하고 있다. 필요할 경우 해당 블로그로 이동해서 확인해보면 좋을 것 같다.

 

b. Workbench와의 차이

 기존에 workbench에서는 확인할 수 없었던 information_schema, performance_schema, mysql 이라는 친구를 DB Browser에서 확인하게 되었다. 이는 workbench의 Edit > Preferences > SQL Editor tab 의 Sidebar 항목의 Show Metadata and Internal Schemas 를 체크하는 것으로 확인 가능하게 되었다.

 여기에서 볼 수 있는 mysql schema 아래에서 test 했던 tbl_memo table을 발견할 수 있었다.

 

c. 왜 하필 mysql schema인가? 다른 것을 쓸 수는 없을까?

# DB Source URL
spring.datasource.url=jdbc:mysql://<IP>:<Port>/<DB name>?useSSL=false&useUnicode=true&serverTimezone=Asia/Seoul

 문제 해결을 위한 마지막 과정에 도달했다. 다른 schema를 사용할 수는 없을까? 이는 또다시 DB Source URL에서 답을 구할 수 있었다. 필자는 DB name에 MySQL을 작성했는데, 이 이름이 schema의 이름일 가능성을 생각하게 되었다. 그래서 이 자리를 'recipository' 로 변경한 후 test를 진행했을 때, 해당 schema에 table이 만들어지는 것을 확인할 수 있었다. 즉, 기존에 입력했던 MySQL이 mysql로 인식되어 해당 schema에 table이 만들어졌던 것이다.

 필자는 처음에 DB name에 MySQL을 설치할 때 입력했던 MySQL을 생각했다. 하지만 이것은 Windows Service Name이고 database의 이름이 아니다. 따라서 필자의 잘못된 생각도 오류에 직면하는 하나의 원인이 되었다고 할 수 있다. 이를 확인 후 필자는 해당 위치를 recipository로 변경해주었다.

 

 

번외 참고

JDBC Connection 객체를 생성해서 연결하는 방법도 있었다.[각주:3] [각주:4]

 

 

연결 참고 : [Spring Boot] MySQL & JPA 연동 및 테스트 (Gradle 프로젝트) — 슬기로운 개발생활 (tistory.com)

 

Reference

댓글