일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- @Autowired
- nestjs auth
- Spring
- 코테
- 프로그래머스
- git
- 카카오
- TypeORM
- 시스템호출
- spring boot
- C언어
- 카카오 코테
- C++
- @Component
- 가상면접사례로배우는대규모시스템설계기초
- Nodejs
- 코딩테스트
- thymeleaf
- OpenCV
- 알고리즘
- 카카오 알고리즘
- python
- 컴포넌트스캔
- 해시
- nestjs typeorm
- 스프링
- 파이썬
- 구조체배열
- AWS
- nestJS
- Today
- Total
공부 기록장 💻
[Spring] 스프링 DB 접근 기술 1 - H2 데이터베이스 설치 및 연결, 순수 JDBC API 이용 (Open-Closed Principle, Dependency Injection) 본문
[Spring] 스프링 DB 접근 기술 1 - H2 데이터베이스 설치 및 연결, 순수 JDBC API 이용 (Open-Closed Principle, Dependency Injection)
dream_for 2023. 1. 16. 15:55인프런 "스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술" 정리
스프링 DB 접근 기술 시리즈 정리
1. 순수 JDBC (현재)
지금까지 스프링에 회원 서비스를 예제로 만들 때, Map 을 이용하여 Java 내부 메모리를 임시 데이터 저장소로 사용하였다. 이제 외부 Database와 연결하여 데이터들을 저장하고 관리하도록 해보자.
우선 가장 간단하게 사용할 수 있는 브라우저 기반의 콘솔 모드를 제공하는 H2 Database에 대해 알아보고, 이를 설치하여 사용해보자.
H2 database 란?
H2 데이터베이스는 별다른 설치를 요구하지 않으며, 용량이 가벼워 개발용 로컬 DB로 사용하기 좋은 DBMS이다.
H2 DB의 특징
- Java 기반의 오픈소스 관계형 데이터베이스 관리 시스템(DBMS)
- 서버(Server) 모드와 임베디드(Embedded) 모드의 인메모리 DB 기능을 지원
- 브라우저 기반의 콘솔 모드 이용 가능
- 별도 설치과정이 없고 2.5MB 이하의 저용량 DB
- 표준 SQL의 대부분을 지원
- 로컬환경 및 테스트 환경에서 많이 사용됨.
실제 운영은 MySQL 또는 AWS, Amazon Aurora를 많이 사용하지만, JPA는 H2DB나 오라클, MySQL에 맞추어 해당 DB에 맞추어 sql문을 만들어 주므로 로컬에서는 H2 Database로 테스트를 많이 진행한다고 한다.
H2 데이터베이스 설치
우선 아래 링크에서 H2 Database Engine 을 다운로드 받자.
https://www.h2database.com/html/main.html
아래 링크에서는 2.1.214 version의 platform-independent.zip 파일을 다운로드 받자.
https://www.h2database.com/html/download-archive.html
다운로드 받은 파일의 압출 풀기를 실행하고, h2.bat 배치 파일을 실행하도록 하자.
위 배치 파일을 실행하면, 아래와 같이 session id를 포함한 임의의 경로와 로그인 화면이 나타나는 것을 확인할 수 있다.
위에서 한 번 연결 버튼을 눌러 데이터베이스를 생성하자.
~/test.mv.db 파일이 생성된 것을 확인할 수 있다. 위 파일을 제거해주도록 하자.
Windwos에서는 아래의 command 를 통해 해당 파일을 삭제할 수 있다.
del "test.mv.db"
아래와 같이 삭제 된 것을 확인할 수 있다.
이제 다시 돌아가 이번에는 JDBC url을 jdbc:h2:tcp://localhost/~/test 로 변경하여 소켓을 통해 접근하도록 설정하자.
이후에 경로의 앞부분을 localhost:8082/login ~ 으로 변경하여 접속하도록 하자.
아래와 같은 웹 브라우저 화면이 나타난다.
이제 다음의 SQL 문을 작성하여 member 테이블을 생성해보자.
기본 1의 값부터 자동으로 auto increment 되는 pk 값인 id와 varchar형 name을 속성으로 포함하였다.
drop table if exists member CASCADE;
create table member
(
id bigint generated by default as identity,
name varchar(255),
primary key (id)
);
좌측에 member 테이블이 생성된 것을 확인할 수 있다.
이제 spring, spring2 의 name을 갖는 value를 삽입해보자.
다음의 select 문을 실행하여 확인해보면 두 값이 잘 저장된 것을 확인할 수 있다.
위의 sql 문은 스프링 프로젝트 내 sql 패키지를 만들어 저장하여 보관해두자.
순수 JDBC API를 통한 DB 접근
이제 JDBC API를 이용하여 H2 데이터베이스의 Datasource와 연결하여 데이터베이스에 접근하여 관리하는 방법에 대해 알아보자.
1. 환경설정
우선 기본적인 환경을 세팅해보도록 하자.
1) build.gradle 파일에 jdbc, h2 db 관련 라이브러리 의존성 추가
build.gradle 파일의 dependencies 부분에 jdbc와 h2db와 관련된 라이브러리를 추가하자.
2) 스프링 부트 데이터베이스 연결 설정 추가
다음으로 application.properties 파일에 datasource의 경로, datasource 드라이버 클래스를 h2 Driver로, 그리고 h2 db의 username은 기존의 sa로 설정하자.
2. JDBC 리포지터리 구현
이제 JdbcMemberRepository 구현체 내부를 작성해보자.
순수 JDBC API로 직접 코딩하는 것은 옛 일이기 때문에, sql 문을 통해 직접 h2 database와 jdbc를 통해 어떻게 연결하는지만 간단하게 살펴보고 넘어가도록 하자.
3. 스프링 설정 변경 (Configuration)
생성자에 준비할 DataSource 객체를 추가해주도록 한다. DataSource는 데이터베이스 커넥션을 획득할 때 사용하는 객체로, spring boot는 데이터베이스 커넥션 정보를 바탕으로 DataSource를 생성하고 스프링 빈으로 만들어두어 의존성 주입을 얻을 수 있게 된다.
그리고 MemberRepository 객체는 기존 내부 메모리를 이용하는 MemoryMemberRepisotry 구현체가 아닌, JDBC API를 이용해 H2 Database 를 이용하는 JdbcMemberRepisotry 구현체로 설정하자.
검증
이제 위에서 작성된 JDBC Repository를 h2 console 에서 sql문을 이용해 검증해보자.
새로운 회원을 insert하는 save() 메서드,
전체 회원을 조회하는 findAll() 메서드,
id 와 name 을 이용해 조회하는 findById(), findByName() 을 확인해보도록 하자.
member 테이블의 전체 튜플을 h2 console 8082 port와 로컬 서버 8080 port에서 조회하면 위와 같다.
메서드에서 중복되는 이름을 갖는 회원의 save 를 제어하는 코드가 포함되어 있지 않기 때문에, NAME이 중복되는 값이 이미 여럿 존재하는 상황이다.
여기서 이미 존재하는 name인 spring1 의 값을 갖는 회원을 insert하면
그대로 위와 같이 잘 저장된다.
findByName() 에 작성된 바와 같이, name의 값이 같은 튜플은 모두 리턴됨을 확인할 수 있다.
findById() 도 마찬가지로 조회할 수 있다.
정리, 스프링의 DI와 OCP 원칙
지금까지 기존 스프링 내부 메모리를 사용하여 임시 데이터베이스의 역할을 하는 MemoryMemberRepository, 그리고 순수 JDBC API를 이용해 h2 database와 연결한 JdbcMemberRepository를 살펴보았다. 이 두 Repository 중 어느 것을 선택하느냐는 SpringConfig 설정 클래스에서 Bean 으로 등록한, MemberRepository를 반환하는 memberRepisotry 메서드 내에서 어떤 객체를 생성하느냐에 따라 달려 있었음을 확인할 수 있었다.
MemberRepository라는 interface를 두고, 구현체만 변경함으로써 사용할 데이터베이스가 변경된 것이다.
스프링 컨테이너에서는 의존성 주입(Dependency Injection)과 객체 지향적 설계를 통해,
기존 구현 레벨의 코드를 수정하지 않고, 설정만으로 구현 클래스를 변경하는 기능을 제공하고 있다.
이러한 기능을 개방-폐쇄 원칙(OCP, Open-Closed Principle) 이라 하며, 확장에는 열려 있고, 수정/변경에는 닫혀있음을 의미한다.
그리고 우리는 위와 같은 설계 방식을 스프링의 가장 큰 장점 중 하나로 볼 수 있다.