우리가 만들 SBB는 질문 답변 게시판이다. 질문이나 답변을 작성하면 데이터가 생성된다.
그러므로 데이터를 저장하거나 조회하거나 수정하는 등의 기능을 구현해야 한다.
웹 서비스는 데이터를 처리할 때 대부분 데이터베이스를 사용한다.
그런데 데이터베이스를 사용하려면 SQL 쿼리(query)라는
구조화된 질의를 작성하고 실행하는 등의 복잡한 과정이 필요하다.
이때 ORM(object relational mapping)을 이용하면 자바 문법만으로도 데이터베이스를 다룰 수 있다.
즉, ORM을 이용하면 개발자가 쿼리를 직접 작성하지 않아도 데이터베이스의 데이터를 처리할 수 있다.
이 책은 독자가 데이터베이스 개념이나 SQL 쿼리의 기초는 안다고 가정한다.
그러나 독자가 이런 기초지식이 없어도 이 책의 실습을 따라 하고 내용을 이해하는데 무리가 없도록 구성했다. ORM은 데이터베이스에 데이터를 저장하는 테이블을 자바 클래스로 만들어 관리하는 기술로 이해해도 좋다.
ORM
SQL 쿼리와 ORM을 비교해 보자. 다음과 같은 형태로 구성된 질문 테이블에 데이터를 입력한다고 가정해 보자.
[question 테이블 구성 예]
id | subject | content |
1 | 안녕하세요 | 가입 인사드립니다 ^^ |
2 | 질문 있습니다 | ORM이 궁금합니다 |
... | ... | ... |
표에서 id는 각 데이터를 구분하는 고윳값이다.
데이터베이스의 설정을 통해 값이 자동으로 증가되어 저장되도록 할수 있다.
이렇게 구성된 question 테이블에 새로운 데이터를 삽입하는 쿼리는 보통 다음처럼 작성한다.
insert into question (subject, content) values ('안녕하세요', '가입 인사드립니다 ^^');
insert into question (subject, content) values ('질문 있습니다', 'ORM이 궁금합니다');
하지만 ORM을 사용하면 쿼리 대신 자바 코드로 다음처럼 작성할 수 있다.
다음코드는 작성할 필요없이 눈으로만 확인하자.
Question q1 = new Question();
q1.setSubject("안녕하세요");
q1.setContent("가입 인사드립니다 ^^");
this.questionRepository.save(q1);
Question q2 = new Question();
q2.setSubject("질문 있습니다");
q2.setContent("ORM이 궁금합니다");
this.questionRepository.save(q2);
위와 같이 ORM을 이용한 데이터의 삽입 예제는 코드 자체만 놓고 보면 양이 많아 보이지만
별도의 SQL 문법을 배우지 않아도 된다는 장점이 있다.
코드에서 Question은 자바 클래스이며, 이처럼 데이터를 관리하는 데 사용하는 ORM 클래스를 엔티티(Entity)라고 한다. ORM을 사용하면 내부에서 SQL 쿼리를 자동으로 생성해 주므로 직접 작성하지 않아도 된다.
즉, 자바만 알아도 데이터베이스에 질의할 수 있다.
ORM의 장점을 더 알아보자
ORM을 이용하면 데이터베이스 종류에 상관 없이 일관된 코드를 유지할 수 있어서 프로그램을 유지·보수하기가 편리하다. 또한 내부에서 안전한 SQL 쿼리를 자동으로 생성해 주므로
개발자가 달라도 통일된 쿼리를 작성할 수 있고 오류 발생률도 줄일 수 있다.
JPA 란?
스프링부트는 JPA(Java Persistence API)를 사용하여 데이터베이스를 처리한다.
JPA는 자바 진영에서 ORM(Object-Relational Mapping)의 기술 표준으로 사용하는 인터페이스의 모음이다.
JPA는 인터페이스이다. 따라서 인터페이스를 구현하는 실제 클래스가 필요하다.
JPA를 구현한 대표적인 실제 클래스에는 하이버네이트(Hibernate)가 있다.
SBB도 JPA + 하이버네이트 조합을 사용한다.
H2 데이터베이스
JPA를 사용하기 전에 데이터를 저장할 데이터베이스를 설치해 보자.
개발시에는 Oracle, MSSQL 등의 굵직한 데이터베이스 보다는
설치도 쉽고 사용도 편리한 H2 데이터베이스를 많이 사용한다.
H2 데이터베이스
H2 데이터베이스는 주로 개발용이나 소규모 프로젝트에서 사용되는 파일 기반의 경량 데이터베이스이다. 개발시에는 H2를 사용하여 빠르게 개발하고 실제 운영시스템은 좀 더 규모있는 DB를 사용하는 것이 일반적인 개발 패턴이다.
다음과 같이 H2 데이터베이스를 설치하자.
[파일명: /sbb/build.gradle]
(... 생략 ...)
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
developmentOnly 'org.springframework.boot:spring-boot-devtools'
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
runtimeOnly 'com.h2database:h2'
}
(... 생략 ...)
그리고 "Refresh Gradle Project"를 실행하여 필요한 라이브러리를 설치하자.
runtimeOnly
build.gradle 파일의 runtimeOnly는 해당 라이브러리가 런타임(Runtime)시에만 필요한 경우에 사용한다.
컴파일(Compile)시에만 필요한 경우에는 runtimeOnly 대신 compileOnly를 사용한다.
설치한 H2 데이터베이스를 사용하기 위해서는 설정을 해야 한다. 다음과 같이 application.properties 파일을 수정하자.
현재 application.properties 파일에는 아무런 내용이 없을 것이다.
[파일명: /sbb/src/main/resources/application.properties]
# DATABASE
spring.h2.console.enabled=true
spring.h2.console.path=/h2-console
spring.datasource.url=jdbc:h2:~/local
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=
각각의 항목에 대해서 알아보자.
- spring.h2.console.enabled - H2 콘솔의 접속을 허용할지의 여부이다. true로 설정한다.
- spring.h2.console.path - 콘솔 접속을 위한 URL 경로이다.
- spring.datasource.url - 데이터베이스 접속을 위한 경로이다.
- spring.datasource.driverClassName - 데이터베이스 접속시 사용하는 드라이버이다.
- spring.datasource.username - 데이터베이스의 사용자명이다. (사용자명은 기본 값인 sa로 설정한다.)
- spring.datasource.password - 데이터베이스의 패스워드이다. 로컬 개발 용도로만 사용하기 때문에 패스워드를 설정하지 않았다.
그리고 spring.datasource.url에 설정한 경로에 해당하는 데이터베이스 파일을 만들어야 한다.
위에서 spring.datasource.url을 jdbc:h2:~/local 로 설정했기 때문에
사용자의 홈디렉터리(~ 에 해당하는 경로) 밑에 local.mv.db 라는 파일을 생성해야 한다.
만약 jdbc:h2:~/test라고 설정했다면 test.mv.db 라는 파일을 생성해야 한다.
사용자의 홈디렉터리는 윈도우의 경우에는 C:\Users\(사용자명) 이고 맥OS의 경우에는 /Users/(사용자명) 이다.
본인이 사용하는 OS에 맞는 홈디렉터리에 local.mv.db 파일을 생성하자. 파일은 내용 없이 빈파일로 생성한다.
맥 OS에서 local.mv.db 파일 생성하기
pahkey@mymac ~ % touch local.mv.db
여기까지 마무리 되었으면 이제 H2 콘솔을 통해 데이터베이스에 접속할 수 있다.
브라우저에서 다음의 URL 주소로 H2 콘솔에 접속해 보자.
- http://localhost:8080/h2-console
그러면 다음과 같은 H2 콘솔화면을 볼수 있다.
한국어를 지원하기 때문에 언어 설정을 "한국어"로 설정할수 있다.
콘솔 화면에서 JDBC URL 경로를 application.properties 파일에
설정한 jdbc:h2:~/local로 변경하고 "연결" 버튼을 눌러보자.
그러면 다음과 같이 접속된 화면을 볼수 있다.
JPA 환경설정
H2 데이터베이스를 사용할 준비가 완료되었다. 이제 자바 프로그램에서 H2 데이터베이스를 사용할 수 있게 해야한다.
자바 프로그램에서 데이터베이스에 데이터를 저장하거나 조회하려면 JPA를 사용해야 한다.
하지만 JPA를 사용하기 전에 JPA를 사용하기 위한 준비 작업이 필요하다.
JPA를 사용한 데이터 처리는 조금 후에 자세히 알아본다.
다음처럼 build.gradle 파일을 수정하자.
[파일명: /sbb/build.gradle]
(... 생략 ...)
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
developmentOnly 'org.springframework.boot:spring-boot-devtools'
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
runtimeOnly 'com.h2database:h2'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
}
(... 생략 ...)
그리고 "Refresh Gradle Project"로 변경사항을 적용하면 JPA 라이브러리가 설치된다.
implementation
build.gradle 파일의 implemetation은 해당 라이브러리 설치를 위해 일반적으로 사용하는 설정이다.
implemetation은 해당 라이브러리가 변경되더라도 이 라이브러리와 연관된 모든 모듈들을 컴파일하지 않고
직접 관련이 있는 모듈들만 컴파일하기 때문에 rebuild 속도가 빠르다.
그리고 JPA 설정을 위해 application.properties 파일을 수정하자.
[파일명: /sbb/src/main/resources/application.properties]
# DATABASE
spring.h2.console.enabled=true
spring.h2.console.path=/h2-console
spring.datasource.url=jdbc:h2:~/local
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=
# JPA
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.H2Dialect
spring.jpa.hibernate.ddl-auto=update
추가한 항목을 간단하게 살펴보자.
- spring.jpa.properties.hibernate.dialect - 데이터베이스 엔진 종류를 설정한다.
- spring.jpa.hibernate.ddl-auto - 엔티티를 기준으로 테이블을 생성하는 규칙을 정의한다.
spring.jpa.hibernate.ddl-auto
위 설정에서 spring.jpa.hibernate.ddl-auto를 update로 설정했다. update와 같은 설정값에 대해서 간단히 알아보자.
- none - 엔티티가 변경되더라도 데이터베이스를 변경하지 않는다.
- update - 엔티티의 변경된 부분만 적용한다.
- validate - 변경사항이 있는지 검사만 한다.
- create - 스프링부트 서버가 시작될때 모두 drop하고 다시 생성한다.
- create-drop - create와 동일하다. 하지만 종료시에도 모두 drop 한다.
개발 환경에서는 보통 update 모드를 사용하고 운영환경에서는 none 또는 validate 모드를 사용한다.
'JAVA > SpringBoot CRUD Board' 카테고리의 다른 글
[VSCODE] SpringBoot CRUD게시판 만들기 - 레포지토리(Repository) (0) | 2022.07.01 |
---|---|
[VSCODE] SpringBoot CRUD게시판 만들기 - 엔티티(Entity) (0) | 2022.07.01 |
[VSCODE] SpringBoot CRUD게시판 만들기 - 컨트롤러 (0) | 2022.06.30 |
[VSCODE] SpringBoot CRUD게시판 만들기 - 프로젝트의 구조 (0) | 2022.06.30 |
[VSCODE] SpringBoot CRUD게시판 만들기 - Lombok(롬복) (0) | 2022.06.30 |