[SpringBoot] Maria DB 로컬 호스팅 및 JDBC, JPA, lombok // CamelCase 유지하기

반응형

 

 

강의는 Azure를 이용한 MySQL 호스팅을 사용할 것으로 되어 있지만, 무료 데이터베이스 툴인 Maria가 Spring과 함께 많이 사용되고 있는데다 MySQL은 이미 전 회사에서도(ㅎㅎ) 지겹게 경험한 적이 있어 Maria로 실습하기 위해 과정을 남겨 보았다.

 

 

! 시작하기 전에, lombok을 사용하면 마지막에 Getter와 Setter를 자동으로 만들게 해 주는 어노테이션을 사용할 수 있어 편하니 설치를 권장한다.

IntelliJ를 사용할 경우, Setting -> Plugins에서 lombok을 검색하면 Install 할 수 있다.

롬복 플러그인을 설치해준다.

 

 

그리고 이 롬복을 정상적으로 사용하기 위하여 annotation processors라는 메뉴에서 

Enable annotation processing 항목을 체크해준다.

들어가자마자 바로 보임!

 

 

사전 준비는 끝났다. 그럼 이제 마리아 DB를 설치하고, 데이터를 만든 다음, JDBC로 스프링 부트 프로젝트에 연결하여, JPA로 자바 언어를 이용해 SQL DB를 소스코드 내에서 다루어 보자. 

 

 

1. 마리아 DB를 설치한다.

 

마리아 DB는 아래 웹사이트에서 다운로드 할 수 있다. 

https://mariadb.com/kb/en/postdownload/mariadb-server-11-6-2/

 

MariaDB Server 11.6.2

<div class="pdl-cta"> Thank you for downloading. Create your MariaDB account to receive download release notifications, product updates an...

mariadb.com

 

 

위 페이지에서 자신에게 맞는 운영체제를 선택해 Download를 클릭하면, 즉시 다운된다.

 

 

 

설치 진행 중 root 유저 정보를 설정하는 창에서 password를 설정한다.

아래는 모든 char의 set을 기본적으로 UTF8로 설정한것인지 묻는 체크박스인데, 필요하다면 체크한다.

 

 

root 유저 정보 설정

 

 

 

위 설정을 완료하고 나면, 포트 번호를 설정하는 창이 뜬다.

필요할 경우 수정해도 괜찮지만, 일반적으로 집에서 실습할 때에는 수정할 필요가 없다.

 

해당 포트가 사용 가능한 상태인지 보려면, cmd 창을 켜 아래 명령어를 입력하면 된다. 엔터를 쳤을 때 아무 결과가 뜨지 않는다면 사용 가능한 상태이다.

 

// 3306 포트가 사용중인지 확인하는 cmd 명령어.
netstat -ano | findstr 3306

 

3306 포트로 설정

 

 

다만 나는 일 때문에 내 컴퓨터에 mySQL을 설치해 둔 상태이므로, 3307이라는 다른 포트를 할당해 주었다. 3306 포트가 사용중일 경우, 아래와 같이 출력된다.

 

3306 포트가 사용중인 모습. LISTENING은 해당 포트가 현재 열려 있으며, 외부의 연결을 기다리고 있는 상태임을 가리킨다.

 

 

마리아 DB를 설치하면 HeidiSQL이라는, 데이터베이스 관리 도구가 함께 설치된다.

평소에는 DBeaver를 사용하지만, 설치된김에 사용해보기로 하였다. 

 

HeidiSQL을 처음 실행한 모습.

 

 

위에서 신규 버튼을 누르면, 새로운 데이터베이스를 만들 수 있다.

클릭된 세션을 우클릭하면 이름도 변경할 수 있는데, test로 변경해 주었다.

 

또한 3307 포트를 사용하기로 하였으므로 포트 번호를 바꾸었고, 암호에는 처음 root 유저를 만들 때 설정하였던 비밀번호를 입력했다.

 

 

 

 

* DBeaver에서 MariaDB를 연결하는 방법

 

1. Connect to a database에서 마리아 DB를 검색한다.

 

mariaDB의 상징은 물개

 

 

2. 내가 설정했던 port 번호와 root의 비밀번호를 입력하고 완료를 클릭한다.

 

Driver properties를 누르면 필요한 것들이 설치된다.

 

 

아래와 같이 연결된다.

 

 

 

2. 설치한 mariaDB에 데이터베이스를 하나 만들고, SpringBoot 프로젝트에 연결한다.

 

test 세션에 Base 데이터베이스를 만들고, User이라는 테이블을 만들 것이다.

 

Base라는 데이터베이스를 만든다.

 

 

테이블은 명령어로도 생성할 수 있고, GUI 도구로 생성할 수도 있다.

 

GUI 도구도 잘 되어있기 때문에 편하다.

 

 

컬럼 또한 HeidiSQL을 이용해 바로 넣을 수 있다. 테이블 생성하는 곳의 +추가 버튼을 클릭하면 된다.

 

userId, loginId, password, name, nickname, age를 생성하되 userId는 AutoIncrement가 적용된 PrimaryKey로 설정할 것이다.

 

 

userId에 primaryKey를 설정해주었다. 우클릭 하고 새 인덱스 생성에 마우스 오버 하면, Primary를 클릭할 수 있다. (현재는 이미 설정되어서 블록 처리된 상태)

 

 

또한 해당 userId의 '기본값' 란을 클릭하면, 위와 같이 선택 옵션 창이 뜬다. 여기서 AUTO_INCREMENT를 클릭하여 자동으로 증가하는, 그 테이블만의 고유한 id를 설정해줄 수 있다.

 

저장을 클릭해야 테이블이 진짜로 생성된다.

 

 

위 과정을 SQL 쿼리로 작성하면 다음과 같다.

CREATE TABLE `User` (
	`userId` INT NOT NULL AUTO_INCREMENT,
	`loginId` VARCHAR(50) NULL DEFAULT NULL,
	`password` VARCHAR(50) NULL DEFAULT NULL,
	`name` VARCHAR(50) NULL DEFAULT NULL,
	`nickname` VARCHAR(50) NULL DEFAULT NULL,
	`age` INT NULL DEFAULT NULL,
	PRIMARY KEY (`userId`)
)
COMMENT='유저의 고유 id, loginId, name, nikname 등 user 정보가 담겨있는 테이블.'
COLLATE='utf8mb4_uca1400_ai_ci'
;

 

 

데이터 또한 GUI 도구로 만들어 삽입할 수 있다.

 

userId는 건드리지 않고, 나머지 데이터 열만 클릭하여 입력한 뒤 빈 공간을 누르면 자동으로userId가 설정된다.

 

SQLD도 딴 겸.. SQL로 INSERT INTO 테이블명 (컬럼명) VALUES (값들) 을 통해 추가 데이터를 넣어주었다.

INSERT INTO base.`user` (loginId, PASSWORD, NAME, nickname, age) VALUES ('nomal', 'nomal100', '노멀 유저', '일반 유저', 20);

 

 

두 행의 데이터가 생성된 모습

 

 

 

 

3. 스프링부트에 JDBC를 이용하여 MariaDB를 연결한다.

 

* 여기서 잠깐, JDBC란 무엇일까?

 

JDBC (Java Database Connectivity)

  • 정의: Java에서 데이터베이스와 연결하기 위한 표준 인터페이스. 자바 프로그램에서 SQL 쿼리를 실행하고 데이터베이스와 상호작용할 수 있게 해준다. 즉, 자바 언어를 사용하여 데이터베이스를 다룰 수 있도록 하는 라이브러리라고 할 수 있다.
    Node.js로 따지자면, mongodb 라이브러리와 같다. 자바 프로그램과 SQL 데이터베이스를 연결하게 해 주며, 저수준의 API를 제공한다. 

  • 역할:
    • 데이터베이스 연결(Connection) 생성.
    • SQL 쿼리 실행(SELECT, INSERT, UPDATE 등).
    • 결과(ResultSet) 처리.
  • 예시: JDBC를 사용해 MySQL/MariaDB와 연결

 

 

 

설치해야 할 최신 maria db용 JDBC 버전은 아래의 사이트에서 확인할 수 있다. 

https://mvnrepository.com/artifact/org.mariadb.jdbc/mariadb-java-client

 

사이트에 따르면 현재 최신 버전은 3.5.1이다.

 

 

 

1. 위 사이트에서 3.5.1을 클릭하고, Gradle을 클릭하면 해당 JDBC 라이브러리를 Gradle를 이용해 다운로드 하게 하는 명령어를 복사할 수 있다.

 

 

 

 

2. 위 명령어를 build.gradle에 입력하고, gradle를 새로고침 해준다. npm install 과 같은 역할을 한다고 생각하면 편하다.

JDBC 라이브러리를 설치해준다.

 

 

 

3. 이제, 데이터베이스 알맹이와 연결해주기 위해 application.properties 를 작성한다.

React로 치자면, 환경변수 파일인 .env와 비슷하다.

 

내가 만든 데이터베이스 이름은 base이고, 사용자 명은 root이며, 비밀번호는 예시로 0000을 입력해 두었다. 

내 포트는 3307이지만, 기본적으로는 3306이므로 예시 코드는 아래와 같이 작성하였다.

spring.datasource.driver-class-name=org.mariadb.jdbc.Driver
spring.datasource.url=jdbc:mariadb://localhost:3306/base // 포트번호/데이터베이스 명
spring.datasource.username=root // 사용자명
spring.datasource.password=0000 // 비밀번호

 

 

 

 

 

 

4. JPA를 설치하여, mariaDB를 사용한다.

 

* JPA란 무엇일까?

 

JPA ( Java Persistence API )

  • 정의: 자바 애플리케이션에서 데이터베이스와 객체 간의 매핑(ORM, Object-Relational Mapping)을 처리하기 위한 표준 인터페이스. Java 진영에서 제공하는 ORM 기술의 표준으로, 데이터베이스와 객체 모델 간의 변환을 간단히 처리할 수 있도록 설계되었다.

    Node.js 개발자에게 이해하기 쉽게 설명해보자면, MongoDB를 사용할 때 이용했던  mongoose 의 역할을 한다고 할 수 있다

  • 역할:
    • 객체와 데이터베이스 간 매핑 .
    • SQL 작성 및 실행 자동화.
    • 데이터 변경 관리.. 등 



 

그럼 이제 자바 언어를 활용해, 자바스크립트로 몽고 디비를 다룬 몽구스처럼, 자바 언어로 SQL DB를 다루기 위하여 JPA라는 라이브러리를 설치해보자.

 

JPA에는 Hibernate, EclipseLink, OpenJPA가 존재한다. 나는 요즘 가장 많이 사용되는 Hibernate를 채택하였다. 

 

 

1. 먼저, build.gradle에 아래 문장을 추가하여 그래들을 새로고침 해 라이브러리를 설치한다.

implementation 'org.springframework.boot:spring-boot-starter-data-jpa'

 

 

2. application.properites에 아래 사항을 추가해준다. 'JPA 엔티티 설계' 와 '실제 테이블 상태' 를 비교해, 차이점이 있다면 그를 테이블에 반영하게 하는 옵션이다. 

spring.jpa.hibernate.ddl-auto=update

 

 

2-1. 만일 실행할 때 DB 입출력 시 SQL을 따로 실행창에 출력하고 싶다면, application.properties에 아래 문장을 추가한다.

spring.jpa.properties.hibernate.show_sql=true

 

 

추가로,  JPA는 CamelCase를 자동으로 snakeCase로 변환한다. 그 설정을 무시하기 위해 아래 사항을 추가해 주었다.

spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
spring.jpa.hibernate.naming.implicit-strategy=org.hibernate.boot.model.naming.ImplicitNamingStrategyLegacyJpaImpl

 

 

 

 

3. 아까 만든 User 테이블을, JPA 문법을 사용하여 소스코드로 옮긴다.

 

 

JPA 문법에서, @Entity 어노테이션은 '테이블' 을 의미한다. 따라서 @Entity를 사용해 클래스를 만들면 그것이 바로 테이블이 된다.

 

그리고 클래스에 변수들을 선언해주면, 그것이 바로 '컬럼' 이 되는 것이다.

 

예를 들어, 위에서 작성한 User 테이블은 아래와 같이 작성한다.

 

import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;

@Entity
public class User {

private int userId;
    private String loginId;
    private String password;
    private String name;
    private String nickname;
    private int age;

}

 

 

그런데 PrimaryKey(기본키) 이면서, 자동으로 증가하는 수인 userId 는 어떻게 설정해 주어야 할까?

JPA 문법에서, 아래의 어노테이션은 '다음 변수가 PrimaryKey이며, AutoIncrement 임을 의미한다.

 

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)

 

 

따라서 userId 바로 위에 아래와 같이 작성해주면 된다.

 

package com.example.demo;

import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;

@Entity
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int userId;

    private String loginId;
    private String password;
    private String name;
    private String nickname;
    private int age;

}

 

 

헌데, 현재 변수들을 class 안에서만 사용하기 위해 private라는 접근자를 붙였으므로 외부에서는 해당 변수의 값을 사용할 수 없는 상태이다. 따라서 해당 변수의 값을 가져오기 위하여 getter와 setter를 만들어 주어야 한다. 

 

import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;

@Entity
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int userId;

    private String loginId;
    private String password;
    private String name;
    private String nickname;
    private int age;

    // Getter와 Setter 추가
    public int getUserId() {
        return userId;
    }

    public void setUserId(int userId) {
        this.userId = userId;
    }

    public String getLoginId() {
        return loginId;
    }

    public void setLoginId(String loginId) {
        this.loginId = loginId;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getNikname() {
        return nickname;
    }

    public void setNikname(String nikname) {
        this.nikname = nikname;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

 

 

그러나 이와 같이 작성하면 매번 테이블을 만들 때마다 똑같은 Getter와 Setter를 만드는 일을 반복해야 하므로, lombok의 @Getter, @Setter 어노테이션을 이용해 이를 자동화시켜줄 수 있다.

 

package com.example.demo;

import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import lombok.Getter;
import lombok.Setter;

@Entity
@Setter
@Getter
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int userId;

    private String loginId;
    private String password;
    private String name;
    private String nickname;
    private int age;

}

 

 

 

4. JPA 문법과 lombok을 이용하여 데이터를 조회한다.

 

테이블에서 데이터를 입력하거나 출력하려면, 항상 다음의 3-step을 밟아야 한다.

 

1. repository를 만들고

2. DB 입출력을 하고자 하는 클래스에서 만든 repository를 등록한 다음,

3. JPA 문법을 사용하여 데이터를 다룬다.

 

 

일단 다음과 같은 User Repository를 만든다.

package com.example.demo;

import org.springframework.data.jpa.repository.JpaRepository;

public interface UserRepository extends JpaRepository<User, Integer> {


}

 

 

그리고 데이터를 조회하고자 하는 페이지에서 이용할 수 있도록, Controller 파일에 데이터베이스를 조회하는 문장을 작성해 주었다. findeAll은 해당 테이블의 '모든' 정보를 가져오라는 JPA 문법이다.

List<User> result = userRepository.findAll();

 

 

이 때 Lombok을 이용하여, @ RequiredArgsConstructor  를 사용해 Constructor를 자동으로 만들도록 설정해 주면 편하다.

@Controller
@RequiredArgsConstructor
public class ItemController {

    private final UserRepository userRepository;

    @GetMapping("/list")
    String list(Model model) {
        List<User> result = userRepository.findAll();
        model.addAttribute("name", "신발");
        return "list.html";
    }
}

 

 

데이터를 가져오려면, getter과 setter를 이용해야 한다. 우리는 lombok을 이용하여 자동으로 생성되도록 하였으므로, 자동완성에 get과 set이 뜬다.

 

System.out.println(result.get(0).getLoginId());

 

 

전체 코드는 다음과 같다.

package com.example.demo;

import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;

import java.util.List;

@Controller
@RequiredArgsConstructor
public class ItemController {

    private final UserRepository userRepository;

    @GetMapping("/list")
    String list(Model model) {
        List<User> result = userRepository.findAll();
        System.out.println(result.get(0).getLoginId());
        model.addAttribute("name", "신발");
        return "list.html";
    }
}

 

 

이제 localhost:8080/list에 들어가면, 아래와 같이 터미널에 println에 출력한 내용이 잘 뜬다.

master 라는 loginId가 나타났다.

 

 

모든 행을 출력하고 싶다면, toString을 일일이 오버라이딩해야한다. 이를 방지하기 위해 @ToString 어노테이션을 사용해 주었다. 

 

package com.example.demo;

import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;

@Entity
@Setter
@Getter
@ToString // ToString 추가 
public class User {
    @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer userId;
    private String loginId;
    private String password;
    private String name;
    private String nickName;
    private Integer age;

}

 

 

아래 코드를 통해 모든 내용을 출력해보자.

result.forEach(System.out::println);

 

 

컨트롤러 전체 코드는 다음과 같다.

package com.example.demo;

import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;

import java.util.List;

@Controller
@RequiredArgsConstructor
public class ItemController {

    private final UserRepository userRepository;

    @GetMapping("/list")
    String list() {
        List<User> result = userRepository.findAll();
        result.forEach(System.out::println);
        return "list.html";
    }
}

 

 

성공~

한글 유니코드가 좀 깨지는 것 말고는 모두 잘 출력된다.

 

 

반응형

'Java > SpringBoot' 카테고리의 다른 글

[SpringBoot] SpringBoot 프로젝트 구조  (0) 2024.12.30
[SpringBoot] Spring Boot Devtools - auto represh  (0) 2024.12.29