JPA Basic 8. Docker + PostgreSQL + PgAdmin4 세팅

zdpk·2024년 3월 14일

JPA Basic

목록 보기
8/11
post-thumbnail

이번 장에서는 PostgreSQL을 직접 설치하여 실제 DB에 저장된 데이터 및 테이블을 볼 수 있도록 환경을 구성해 볼 것이다.

이어지는 장에서 볼 내용을 직접 확인하기 위해 필요하기 때문이다.

Docker 설치

아래 명령어로 Docker Desktop을 설치한다.

macOS 기준이며, Windows인 경우 설치 방법을 직접 찾아보자.

$ brew install docker --cask

💡 반드시 --cask를 붙여야 한다.

$ brew install docker는 Docker Engine만 설치할 뿐, Docker Desktop은 설치하지 않기 때문이다.

--cask는 Engine, Desktop을 모두 설치한다.


PgAdmin4 설치

$ brew install pgadmin4

postgresql에 연결하여 DB 내부를 살펴볼 수 있는 무료 오픈소스 툴이다.

이 외에도 DBEaver, Postico, TablePlus, DataGrip 등의 툴이 있지만 죄다 유료/부분 유료이기도 하고

PgAdmin이 가장 많이 사용되는 공식 Postgres Client이기 때문에 선택했다.

먹고 살기 바쁜데 별거에 다 돈을 쓰고 싶진 않을 것이기 때문에 무료 툴을 사용하는 것도 중요할 것이다.


Spring Project 세팅

IDE나 spring initializr에서 프로젝트를 생성하고 build.gradle를 다음과 같이 수정한 뒤,

$ ./gradlew명령어를 실행하여 의존성을 설치하자.

JDK 17에서 진행하겠다.

// build.gradle
plugins {  
    id 'java'  
    id 'org.springframework.boot' version '3.2.3'  
    id 'io.spring.dependency-management' version '1.1.4'  
}  
  
group = 'x'  
version = '0.0.1-SNAPSHOT'  
  
java {  
    sourceCompatibility = '17'  
}  
  
configurations {  
    compileOnly {  
        extendsFrom annotationProcessor  
    }  
}  
  
repositories {  
    mavenCentral()  
}  
  
dependencies {  
    implementation 'org.springframework.boot:spring-boot-starter-data-jpa'  
    implementation 'org.springframework.boot:spring-boot-starter-web'  
    compileOnly 'org.projectlombok:lombok'  
    annotationProcessor 'org.projectlombok:lombok'  
    testImplementation 'org.springframework.boot:spring-boot-starter-test'  
    runtimeOnly 'org.postgresql:postgresql'  
}  
  
tasks.named('test') {  
    useJUnitPlatform()  
}

application.yaml은 다음과 같이 설정한다.

username, password은 PostgreSQL의 기본값인 postgres로 지정했다.

# application.yaml
spring:  
  datasource:  
    url: jdbc:postgresql://localhost:5432/postgres  
    username: postgres  
    password: postgres  
    driver-class-name: org.postgresql.Driver  
  jpa:  
    hibernate:  
      # 실행할 때마다 Entity와 대응되는 모든 Table DROP & CREATE
      ddl-auto: create
  
    show-sql: true  
    properties:  
      hibernate:  
        format_sql: true  

docker-compose.yaml 작성

docker 명령어를 shell에서 직접 작성 및 실행할 수도 있지만,

오타가 날 수도 있고 귀찮을 것이기 때문에 docker-compose.yaml 파일을 미리 준비했다.

프로젝트 루트에 docker-compose.yaml 파일을 생성한 뒤, 내용을 복붙하자.

# docker-compose.yaml
version: '3'  
  
services:  
  postgres:  
    image: postgres:16  
    restart: always  
    volumes:  
      - ./data:/var/lib/postgresql/data  
    ports:  
      - '5432:5432'
    environment:
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: postgres
      POSTGRES_DB: postgres

이전에 다운받은 Docker Desktop을 실행하고, $ docker-compose up 명령어를 shell에서 실행하자.

❯ docker-compose up
[+] Running 1/1
 ✔ Container jpa_playground-postgres-1  Recreated                                                                                                                                0.4s 
Attaching to postgres-1
postgres-1  | 
postgres-1  | PostgreSQL Database directory appears to contain a database; Skipping initialization
postgres-1  | 
postgres-1  | 2024-03-14 14:45:23.643 UTC [1] LOG:  starting PostgreSQL 16.2 (Debian 16.2-1.pgdg120+2) on aarch64-unknown-linux-gnu, compiled by gcc (Debian 12.2.0-14) 12.2.0, 64-bit
postgres-1  | 2024-03-14 14:45:23.643 UTC [1] LOG:  listening on IPv4 address "0.0.0.0", port 5432
postgres-1  | 2024-03-14 14:45:23.643 UTC [1] LOG:  listening on IPv6 address "::", port 5432
postgres-1  | 2024-03-14 14:45:23.645 UTC [1] LOG:  listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
postgres-1  | 2024-03-14 14:45:23.650 UTC [30] LOG:  database system was shut down at 2024-03-14 14:45:23 UTC
postgres-1  | 2024-03-14 14:45:23.657 UTC [1] LOG:  database system is ready to accept connections

위와 같이 출력 되었다면 잘 실행된 것이다.


User, Post Entity 생성

지난 장에서 만들었던 User, Post Entity를 그대로 생성할 것이다.

// User.java
@Entity  
@Getter  
@Setter  
@Table(name = "\"user\"")  
@NoArgsConstructor(access = AccessLevel.PROTECTED)  
@AllArgsConstructor  
public class User {  
  
  @Id  
  @GeneratedValue(strategy = GenerationType.SEQUENCE)  
  private Long id;  
  
  private String name;  

  @OneToMany(mappedBy = "author")
  private List<Post> posts = new ArrayList<>();  
  
}

// Post.java
@Entity  
@Getter  
@Setter  
@NoArgsConstructor(access = AccessLevel.PROTECTED)  
@AllArgsConstructor  
public class Post {  
  
  @Id  
  @GeneratedValue(strategy = GenerationType.SEQUENCE)  
  private Long id;  
  
  private String title;  
  
  private String content;  

  @ManyToOne  
  private User author;  
  
}

이제 Spring Application을 실행해보자.


PgAdmin4로 PostgreSQL 연결

PgAdmin4를 실행하면 다음과 같은 화면이 나타난다.

Add New Server 버튼을 눌러 Docker로 실행한 PostgreSQL에 연결하자.

General 탭에서 이름을 postgres로 설정한 뒤, Connection 탭으로 이동한다.

위와 같이 정보를 기입한다.

비밀번호도 역시 postgres로 입력하면 된다.

우측 하단의 Save 버튼을 눌러 저장한 뒤, 위와 같은 화면이 보이면 정상적으로 연결된 것이다.

조금 깊지만 좌측 Explorer에서 Servers > postgres > Databases > postgres > Schemas > Tables > post로 이동해보자.

post에서 우클릭 후, Scripts > SELECT Script를 선택하자.

select * from "post";를 입력하고 우측 ▶️ 버튼을 누르면 SQL이 실행되고, 결과가 아래에 출력된다.

저장된 Record와 Column 목록이 보이는 것을 확인할 수 있다.

또한 SQL을 실행하는데 얼마나 시간이 소요 되었는지도 친절하게 알려준다.

54 msec라고 나오는데, milli second의 약자로 1000분의 1초를 의미한다.

0.054초가 걸렸다고 보면 되겠다.

@SpringBootTest  
@Transactional  
@Commit  
class UserTest {  
  
  @Autowired  
  private EntityManager em;  
  
  @Test  
  void test() {  
    Post post = new Post();  
    em.persist(post);  
  }    
}

연결 및 조회는 성공했지만, 아직 DB에 데이터가 존재하지 않는다.

DB에 데이터가 정상적으로 삽입되는지 확인하기 위해 위와 같이 테스트 코드를 작성한 뒤, 실행해보자.

이후 PgAdmin에서 SQL도 다시 실행하면 Record가 정상적으로 삽입된 것을 볼 수 있다.

어떤 필드에도 값을 넣어주지 않았기 때문에 null로 나오는 것이 정상이며,

여태껏 봐왔듯, 어떤 GeneratedValue 전략을 사용하더라도 idem.persist 시점에 자동으로 들어간다는 사실을 잘 알고 있을 것이다.

이제 다음 장으로 넘어가서 연관 관계에 대해 다양한 실험을 진행할 준비가 되었다.

0개의 댓글