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 : 자동 생성 기능을 사용하지 않는다.
- 운영 장비에서는 절대 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
- ddl-auto 옵션 관련 주의할 점!!!!!!!!! (tistory.com) [본문으로]
- Jetbrains DataGrip - MySQL Timezone 접속문제 해결. Server returns invalid timezone. Go to 'Advanced' tab and set 'serverTimezone' property manually. (junho85.pe.kr) [본문으로]
- IntelliJ JDBC 연동(MySQL) (velog.io) [본문으로]
- [JDBC+MYSQL]MYSQL설치부터 IntelliJ 연동까지 (tistory.com) [본문으로]
'프로젝트 > Recipository' 카테고리의 다른 글
[Dev] 22.09.26 signinform.html (feat. Regular Expression, FormData) (0) | 2022.09.26 |
---|---|
[MySQL DB] 22.09.20. InnoDB, Schema와 Database (0) | 2022.09.20 |
[DB] 22.09.18. MySQL workbench 계정 추가 (0) | 2022.09.18 |
[DB] 22.09.17. MySQL 설치 (0) | 2022.09.18 |
[Dev] 22.09.15. Thymeleaf 를 사용하는 이유 (0) | 2022.09.15 |
댓글