728x90
반응형

1. 기존에 서버를 배포하던 방식

기존에는 수동으로 배포를 진행하였다. 보통 배포하는 서버는 EC2를 사용하고, Docker를 이용해서 배포하였다.

  1. Gradle을 사용해서 Spring 프로젝트를 빌드하여 jar 파일을 만든다.
  2. Dockerfile을 사용하여서 도커 이미지를 만든다.
    1. 사용한 Dockerfile은 다음과 같다.
    2. FROM openjdk:11 ARG JAR_FILE=build/libs/*.jar COPY ${JAR_FILE} app.jar ENTRYPOINT ["java","-jar","/app.jar"]
  3. 생성된 Docker 이미지를 Docker hub에 push한다.
  4. EC2를 ssh를 통해 접속한다
  5. EC2에서 docker hub의 이미지를 pull해서 가져온다.
  6. sudo docker pull (도커HOST)/(이미지 이름) // sudo docker pull jakeheon/MZTI
  7. docker run을 통해 실행한다.
  8. // 그냥 실행 sudo docker run jakeheon/MZTI // 백그라운드 실행 sudo docker run -it -d jakeheon/MZTI // 포트 80으로 실행 sudo docker run -it -d -p 80:8080 jakeheon/MZTI

문제점

해당 방식은 수동으로 진행하는 것이라서 시간도 걸리고 불편하다. 그리고 여러 사람이 같이 협업을 할 경우 충돌 문제가 생길 수 있다. 특정 branch에 올릴 때 해당 branch를 배포 자동화하려고 하였다.

2. GithubAction 사용해서 자동으로 CI/CD 진행하기

1. GithubAction이란?

자동으로 CI, CD를 도와주는 Github 내장 프로그램

2. GithubAction VS Jenkins

Github Actions or Jenkins? Making the Right Choice for You

3. GithubAction으로 간단한 Spring Project 배포하기

  1. 먼저 Spring Project를 하나 만들고 Github Repository와 연결해준다.
    1. 사용 기술 : java 11, springboot 2.7.15
  2. github에 직접 들어가서 Action탭에서 yml파일을 작성해준다.
    1. 해당 yml 파일에 적힌대로 실제 코드가 git에 push되면 알아서 실행을 해준다.
    2. 만약 실패할 경우… 메일로 실패했다고 전달해온다. (며칠간 100개는 받은것 같다..)
    3. 먼저 아래의 코드를 실행할 때 secret키들은 따로 저장해두어야 한다.
      1. Github Repository에 setting에 action setting에 들어가서 설정할 수 있다.
      2. 이 부분은 다른 블로그에도 많이 있으므로 따라하면 된다.
    4. 정말 간단한데.. 하나씩 test해보면서 로그를 보고 어디가 문제인지 찾으면 된다. (너무 고생한것들을 트러블 슈팅에 기록하였다.)
    5. 여기서 ‘- name: ‘ 이게 하나의 단위이다. 이 상태대로 stage가 나누어지기 때문에 log를 볼때 해당 사항을 잘 살펴보면 된다.
    6. name: Java CI with Gradle on: push: branches: [ "main" ] pull_request: branches: [ "main" ] permissions: contents: read jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - name: Grant execute permission for gradlew and build run: | chmod +x gradlew ./gradlew build - name: Set up JDK 11 uses: actions/setup-java@v3 with: java-version: '11' distribution: 'temurin' - name: init with Gradle uses: gradle/gradle-build-action@v2 - name: Build with Gradle run: | chmod +x ./gradlew ./gradlew clean build - name: Set up Docker Buildx uses: docker/setup-buildx-action@v1 with: version: v0.7.0 - name: Docker build & push to docker repo run: | docker login -u ${{ secrets.DOCKER_HUB_USERNAME }} -p ${{ secrets.DOCKER_HUB_PASSWORD }} docker build -t jakeheon/githubaction -f Dockerfile . docker push jakeheon/githubaction - name: Build and deploy uses: appleboy/ssh-action@master id: deploy with: host: ${{ secrets.HOST }} username: ubuntu key: ${{ secrets.KEY }} envs: GITHUB_SHA script: | sudo docker stop $(sudo docker ps -aq) sudo docker rm -f $(docker ps -qa) sudo docker pull jakeheon/githubaction sudo docker run -it -d -p 80:8080 jakeheon/githubaction
  3. yml파일 내용 간단 설명gradle로 빌드할 수 있도록 권한을 주는 코드이다. 만약 이 부분에서 잘못된다면 아마 Spring project의 위치 문제일 것이다. run 제일 첫번째 줄에 directory 실행 위치를 찍어보면 알 수 있다. 아래 트러블 슈팅에서 더 자세히 설명하겠다.차례대로 JDK 11을 사용하겠다는 의미와 Gradle을 통해 build하는 과정이다. 아마 이 부분은 위와 같이 directory 문제가 아니라면 오류가 생기지 않을 것이다.Docker를 통해 로그인을 하고, build한 뒤 push 하는 코드이다. Dockerfile의 위치를 잘 확인해야 한다. 지금 여기에는 jakeheon/githubaction으로 내가 만들 이미지로 되어있는데 해당 내용도 secret에 두는 것이 좋은것 같다. 본인이 원하는 호스트와 이미지를 Dockerfile을 이용해서 만드는 코드이다.
    • EC2에 접속해서 배포하는 코드이다. EC2에 접속할 때 필요한 HOST와 KEY를 secret에 저장해둔다. pem.key의 경우 EC2에서 다운받은걸 모두 복사해서 secret에 넣어두면 된다. HOST는 접속하는 EC2의 주소를 의미하므로 ip주소나 DNS주소를 입력하면 된다.
    • 나머지는 원래 배포하던 코드랑 같다. 먼저 실행하고 있는 docker container를 stop 시켜준 뒤, 컨테이너를 삭제하고, 이미지를 Pull 받아서 실행한다.
  4. - name: Build and deploy uses: appleboy/ssh-action@master id: deploy with: host: ${{ secrets.HOST }} username: ubuntu key: ${{ secrets.KEY }} envs: GITHUB_SHA script: | sudo docker stop $(sudo docker ps -aq) sudo docker rm -f $(docker ps -qa) sudo docker pull jakeheon/githubaction sudo docker run -it -d -p 80:8080 jakeheon/githubaction
  5. - name: Set up Docker Buildx uses: docker/setup-buildx-action@v1 with: version: v0.7.0 - name: Docker build & push to docker repo run: | docker login -u ${{ secrets.DOCKER_HUB_USERNAME }} -p ${{ secrets.DOCKER_HUB_PASSWORD }} docker build -t jakeheon/githubaction -f Dockerfile . docker push jakeheon/githubaction
  6. - name: Set up JDK 11 uses: actions/setup-java@v3 with: java-version: '11' distribution: 'temurin' - name: init with Gradle uses: gradle/gradle-build-action@v2 - name: Build with Gradle run: | chmod +x ./gradlew ./gradlew clean build
  7. - name: Grant execute permission for gradlew and build run: | chmod +x gradlew ./gradlew build

3. 트러블 슈팅

1. Spring 프로젝트와 Dockerfile 위치 문제

문제 원인

매번 내가 github repository를 만들 때 잘못하고 있었던 것이다.. (이번으로 다른 프로젝트도 수정해야 할 것같다)

.git의 위치를 항상 Spring project 바깥에 두어서 github action이 해당 프로젝트에 들어올려면 폴더 하나를 더 거쳐야하는 문제가 생겼었다.

예를 들자면, TestRepositorySpring이라는 Spring boot 프로젝트를 생성했을 때 repository이름도 TestRepository라고 한다면 TestRepository 에 .git 파일과 TestRepositorySpring이라는 스프링 프로젝트 파일이 존재하는 것이다. 그럼 github action을 실행하기 위해서는 cd 명령어로 TestRepositorySpring으로 들어가야하는 문제가 생긴다…

동일하게 Dockerfile을 통해 빌드할 때도 Dockerfile을 TestRepositorySpring 안에 있으므로 안되는 문제가 생긴다.

보통 다른 블로그나 글들을 찾아봤을때 나와 같은 문제는 없었던 것 같다. (나만 계속 이상하게 하고 있는 것이므로..) 호오오옥시 나랑 동일한 문제가 있는 것 같다면 아래 방법으로 해결하면 된다.

해결 방법

  1. Spring Project 안에 들어가서 실행해야할 Dockerfile빌드라던가 jar 빌드 등을 할 때, yml에 cd를 통해 해당 폴더로 이동 뒤에 실행한다. (실수하거나 깜빡할 수 있으므로 2번을 그냥.. 하는게 맞는것 같다)
  2. .git을 Spring 프로젝트 안에 둔다.

2. jar 파일 빌드 문제(Error: Invalid or Corrupt jar file /app.jar)

문제 원인

이건 신기하게 Action은 다 성공해서 체크 모양이 떴는데 실제 반영이 안된 문제였다. 그래서 뭐가 문제인지 한참을 고민하다가 EC2에서 docker pull을 받아온 다음에 docker를 실행시켰더니 다음과 같은 메시지가 떴었다.

로그를 봤을 때 빌드는 성공적으로 된 것을 확인했는데 저런 오류 메시지가 발생하였다면 .jar파일이 겹쳐서 생긴문제이다. 즉, gradle로 빌드할 때 (프로젝트 이름)-plain.jar도 생기고, (프로젝트 이름).jar 2개가 생기므로 겹쳐서 오류가 발생한 것이다. 이걸 하나로 만들어줘야 해결된다.

해결 방법

build.gradle에 다음과 같이 작성하면 plain.jar는 생기지 않는다.

jar {
    enabled = false
}

3. 기존 실행하던 컨테이너 중단, 종료 문제

문제 원인

이제 진짜 다 되었다! 했을 때 생긴문제.. Action도 다 잘되고 성공한 것을 보고 처음 배포했을 때 서버ip주소로 잘 접속되는 것까지 확인했는데 생긴 문제다. 이제 코드를 바꿔서 push해서 테스트 해봐야지~ 했는데 실패했다. (바뀌지 않았다.)

실제 EC2에 접속해서 docker 로그를 확인해보니 기존에 실행하던 이미지와 겹쳐서 실행이 안되던 것이였다. 즉, 기존에 잘 돌아가고 있는 컨테이너를 중지하고 새로 배포한 이미지를 컨테이너에 올려야되는데 중지를 안해서 생긴 문제였다. (물론 위에 yml 파일은 해당 오류를 해결한 코드이다.)

해결 방법

yml에 Build and deploy script 맨 위에 다음과 같은 코드를 추가한다. docker container를 stop하고 remove하는 코드이다.

sudo docker stop $(sudo docker ps -aq)
sudo docker rm -f $(docker ps -qa)

4. EC2에 접속할 때 필요한 pem.key를 어떻게 두어야할지 몰랐을 때

문제 원인과 해결 방법

이것도 처음에 너무 고민이였다.. 사실 pem key를 제대로 이해를 안하고 있었던 것 같다. pem key도 단순히 해시 알고리즘을 통해서 바뀐 String일텐데.. 그 생각을 못했던 것 같다. pem.key를 그대로 열어서 secret에 모두 복사해서 붙여넣으면 된다!

4. 앞으로 해결할 기능들

1. Docker-Compose를 이용하여서 데이터베이스와 함께 배포해보기

2. jar로 빌드된 것을 cache를 이용하여서 속도를 빠르게 하기

3. Spring 프로젝트 이외에 React나 언어의 프로젝트도 배포해보기

4. 온프레미스 환경에 배포해보기

728x90
반응형

'백엔드' 카테고리의 다른 글

[JWT] JWT 인증을 사용하는 이유  (2) 2023.10.04
세션  (0) 2023.08.25
[AWS] Elastic BeanStalk 배포와 Trouble Shooting  (0) 2023.05.23
[Spring] Spring으로 웹 개발을 진행할 때 알아야할 정보  (0) 2023.05.23
Gradle  (0) 2022.12.27
728x90
반응형

서버를 도커를 사용해서 배포해야 한다, 도커를 사용하면 신세계를 경험할 수 있다. 이러한 말만 많이 듣고, 정작 배포할 때는 배포파일을 명령어로 EC2로 이동시켜서 실행해 본 경험 밖에 없어서 도커에 대한 개념을 알고 배포까지 해보려고 한다.

먼저, 이 글은 도커에 대한 개념을 공부한 내용이다.

도커의 정의

도커란 개발자가 컨테이너화된 애플리케이션을 빠르게 빌드, 테스트 및 배포할 수 있게 해주는 가상화 도구 라고 한다.

이 말만 들어서는 정의 안에 너무 모르는 말들이 많았다. 가상화, 컨테이너에 대한 용어부터 알고 가겠다.

가상화

가상화란 하나의 물리적 서버 호스트에서 여러 개의 서버 운영 체제를 게스트로 실행할 수 있게 해주는 아키텍쳐이다.

내 물리적 서버는 현재 윈도우를 사용하고 있는데, 우분투나 다른 운영체제를 사용해야 할 경우가 생긴다. 그 때 가상화라는 것을 사용하는 것이다.

 

가상화가 필요한 이유는 서버의 성능을 나누어서 사용하기 위해 필요하다. 하나의 서버를 나누어서 성능을 분산시키고, 분산된 서버들은 각기 다른 서비스를 수행한다. 즉, 내가 여러 서비스를 실행하고 싶을 때, 컴퓨터를 여러 대 사는게 아니라 하나의 서버에서 서버를 여러 개 쓰는 효과를 누리게 된다.

 

가상화를 통해서 사용자가 많은 서비스에는 많은 자원을 할당해주고, 적은 서비스에는 적게 할당해 줄 수 있다.

이런 가상화를 구현해주는 기술은 Hypervisor라는 가상화 기술을 사용한다. Hypervisor는 여러 개의 운영체제를 하나의 Host OS에 생성해서 사용할 수 있게 해주는 소프트웨어이다. 여러 개의 운영체제는 하나 하나가 가상머신 이라는 단위로 구별이 된다.

그럼 Hypervisor는 os들에게 자원도 나누어주고, os들이 요청하는 커널 번역해서 하드웨어에게 전달도 해준다. Hypervisor에 의해 생성되고 관리되는 운영체제는 guest 운영체제라고해서, 각 guest 운영체제는 완전히 독립된 공간과 시스템 자원을 할당받아서 사용하게 된다.

 

그럼 위에서 얘기했던 도커를 사용하는 이유랑 같은거 같다. 그럼 가상화의 어떠한 단점 때문에 도커가 나오게 된 것일까?

가상화를 사용하는 툴은 Virtual Box나 VMWare 같은 것들이 있다. 근데 이러한 가상화 툴의 단점은 Hypervisor를 반드시 거쳐야 하므로 일반 호스트에 비해서 성능 손실이 발생한다. 그리고 가상머신에 guest 운영체제를 사용하기 위한 라이브러리, 커널 등을 전부 포함해서 배포할 때 크기도 커진다.

 

즉, 가상머신을 완벽한 운영체제를 생성할 수 있는 장점이 있긴 하지만, 성능이 떨어지고 용량 문제도 생기는 것이다.

이를 해결하기 위해 나온 것이 컨테이너의 개념이다.

컨테이너

컨테이너란 가상화된 공간을 생성하기 위해서 리눅스 자체 기능을 사용해서 프로세스 단위의 격리환경을 만든다. 여기서 격리 환경을 컨테이너라고 하게 된다.

 

컨테이너의 사전적 의미는 어떤 물체를 격리하는 공간으로 이걸 소프트웨어에서 사용할 때는 파일 시스템+격리된 자원 + 네트워크를 사용할 수 있는 독립된 공간이라는 의미로 가져온다.

 

우리가 아는 컨테이너는 스프링에서 자주보던 서플릿 컨테이너나 IoC 컨테이너, Bean 컨테이너 같은 것들이다. 이런 컨테이너들은 컨테이너에 담긴 것들의 라이프 사이클을 관리해준다. 어떤 것들을 생성하고, 운영하고, 제거까지 컨테이너가 관리해주는 것이다.

 

그럼 도커에서의 컨테이너란 이미지의 목적에 따라서 생성되는 프로세스 단위의 격리환경으로 프로세스의 생명 주기를 관리하는 환경을 제공해준다.

 

컨테이너 안에는 애플리케이션을 구동하는데 필요한 라이브러리와 실행 파일만 존재해서 이미지로 만들게 되면, 이미지 용량도 매우 적다. 여기서 이미지란 컨테이너를 만드는 데 필요한 모든 지시사항과 dependency를 포함하는 템플릿으로 ‘컨테이너를 만들어주는 틀’이라고 생각하면 된다.

 

이 컨테이너를 다루는 기술 중 하나가 도커가 되는 것이다. (도커 이외에도, Red Hat Openshit, ECS, 이런 것들이 있다고 한다..)

 

Q> 그럼 컨테이너를 왜 써야 하는가?
A> 이미지의 실행, 배포가 빨라지고 Host와의 격리를 통해서 독립된 개발을 할 수 있다.

 

여기서 도커는 컨테이너 기술에 여러 기능을 추가한 오픈소스 프로젝트인 것이다.

도커

그럼 컨테이너를 도커는 어떻게 관리하는 것일까? 도커는 Docke Engine을 통해서 컨테이너를 관리할 수 있다. 도커 엔진은 유저가 컨테이너를 쉽게 사용할 수 있게 하는 주체로 컨테이너의 라이프 사이클을 관리해주고 이미지, 볼륨, 네트워크 까지 관리해준다.

그래서 최근 자바 프로젝트는 SpringBoot + Docker + EC2 조합으로 환경을 구성한다고 한다. 그럼 도커 시스템을 구축하고 배포하는 방법을 보겠다.

도커를 통해서 배포하기

먼저 도커를 설치해야 한다. 나는 도커 데스크톱까지 설치해주었다.

그리고 테스트할 SpringBoot 프로젝트를 만들었다. 해당 프로젝트에 Dockerfile을 만들어서 설정을 해주면 된다. 제일 간단한 설정만 따와서 해보았다.

FROM amazoncorretto:11
COPY build/libs/*.jar dockerpr-0.0.1-SNAPSHOT.jar
ENTRYPOINT ["java", "-jar", "dockerpr-0.0.1-SNAPSHOT.jar"]

해당 설정을 해준 뒤, Docker Image를 만들어야 한다. Intellij에서 터미널에서 제일 루트 위치에서 실행시켜주면 된다.

docker build -t jakeheon/dockerpr

그리고 docker images로 도커 이미지가 생성되었는지 확인하면 된다. (잘 안되어서 몇 번 하다보니까 이미지가 잔뜩 생겼다.. 오류는 docker에 로그인을 하지 않았거나(docker login) 파일 위치가 잘못되었거나 하는 경우였다)

그리고 Container를 실행해준다. Host Port와 Container Port를 연결할려고 port를 2개 입력하였다.

docker run -d -p 8080:8080 jakeheon/dockerpr

해당 컨테이너가 실행되고 있음을 명령어로 확인할 수 있다.

docker ps

 

그리고 http://localhost:8080에도 잘 접속된다. 그리고 도커 허브 사이트에 이미지를 푸쉬하면 된다.

docker push jakeheon/dockerpr

EC2에서는 똑같이 해주면 된다.

docker를 설치하고, docker를 실행하고, 도커 허브에 있는 이미지를 풀하면 된다.

그리고 이미지를 실행하면 된다.

그냥 github처럼 우리가 github에 push한 걸 ec2에서 받아오는 느낌과 같다.

[참고 링크]
https://devfoxstar.github.io/java/springboot-docker-ec2-deploy/
https://selfish-developer.com/entry/가상화-기술의-유형

 

가상화 기술의 유형

가상화 기술은 어떤 방식으로 구현하느냐에 따라 크게 Type 1& Type 2로 나뉜다. 직관적으로 이해하기 위해 먼저 그림으로 표현하면 다음과 같다. 위 두 그림의 가장 큰 차이점은 Hypervisor(가상머신)

selfish-developer.com

 

스프링부트를 도커로 EC2에 배포하기 (SpringBoot, Docker, EC2)

SpringBoot + Docker + EC…

devfoxstar.github.io

https://youtu.be/IiNI6XAYtrs

 

728x90
반응형

'CS > TIL' 카테고리의 다른 글

[DevOps] 쿠버네티스 환경구축  (0) 2023.03.29
가상메모리(Virtual Memory)  (0) 2023.02.17
Transaction과 Rollback  (0) 2023.02.14
Logging을 이용한 Database의 Recovery  (0) 2023.02.09
728x90
반응형

데이터베이스 연동(1) - ORM, JPA, Hibernate, Mybatis, JDBC

ORM(Object Relational Mapping)

ORM은 Object Relational Mapping의 줄임말로 객체 관계 매핑을 의미한다. Java와 같은 객체지향 언어에서 의미하는 객체(클래스)와 RDB(Relational Database)의 테이블을 자동으로 연결(mapping)하는 방법이다.

 

클래스는 데이터베이스의 테이블과 연결(mapping)하기 위해 만들어진 것이 아니기 때문에 RDB 테이블과 어쩔 수 없는 불일치가 존재한다. ORM은 이 둘의 불일치와 제약사항을 해결하는 역할이다.

ORM의 장단점

ORM의 장점

  • ORM을 이용하면 쿼리문 작성이 아닌 코드(Method)로 데이터를 조작할 수 있어서 개발자는 객체 모델을 이용하여 비즈니스 로직으로 구성하는데만 집중할 수 있다.
    (물론 내부적으로는 쿼리를 생성하여 DB를 조작한다)
  • 연결하는 정보가 Class로 명시되어 있으면 ERD를 보는 의존도도 낮출 수 있다.
  • 재사용 및 유지보수가 편하다
  • 데이터베이스에 대한 종속성이 줄어든다. 예를 들어 DB를 MySQL에서 PostgreSQL로 변환한다면 쿼리를 새로 짜야되는데 ORM을 사용한다면 쿼리를 수정할 필요가 없다.

 

ORM의 단점

  • 복잡한 서비스의 경우 직접 쿼리를 구현하지 않고 코드로 구현하기 어렵다
  • 복잡한 쿼리를 정확한 설계 없이 ORM만으로 구성하게 되면 속도 저하 등의 성능 문제가 발생할 수 있다.
  • 프로젝트의 규모가 크고 복잡하여 설계가 잘못된 경우, 속도 저하 및 일관성을 무너뜨릴 수 있다.
  • 세분성 : ORM의 자동 설계 방법에 따라 데이터베이스에 있는 테이블의 수와 애플리케이션의 엔티티 클래스의 수가 다른 경우가 생긴다.
  • 상속성 : RDBMS에는 상속이라는 개념이 없다
  • 식별성 : RDBMS는 기본 키로 동일성을 정의하는데 자바는 두 객체의 값이 같아도 다르다고 판단할 수 있다
  • 연관성 : 객체 지향 언어는 객체를 참조함으로써 연관성을 나타내지만 RDBMS에서는 외래키를 삽입함으로써 연관성을 표현한다. 또한 객체지향 언어에서 객체를 참조할 때는 방향성이 존재하지만 RDBMS에서 외래키를 삽입하는 것은 양방향의 관계를 가지기 때문에 방향성이 없다.

JPA(Java Persistence API)

Java Persistence API는 자바 진영의 ORM 기술 표준으로 채택된 인터페이스의 모음이다. (Java에서 제공한다. 즉, ORM을 사용하기 위한 표준 인터페이스들을 모아둔 것이다)

 

이전에는 EJB, 엔티티 빈 이라는 개념들로 사용했는 이를 대체하기 위한 기술이 JPA이다.

 

JPA 또한 실제로 동작하는 것이 아니라 어떻게 동작해야 하는지 메커니즘을 정리한 표준 명세로 생각하면 된다. (즉, 인터페이스 이기 때문에 JPA를 구현하기 위해 Hibernate나 OpenJPA같은 프레임워크를 사용한다. JPA는 구현된 클래스와 연결해주기 위해 사용되는 프레임워크)

 

JPA의 메커니즘을 보면 내부적으로 JDBC를 사용한다. 개발자가 직접 JDBC를 구현하면 SQL에 의존하게 되는 문제 등이 있어 개발의 효율성이 떨어지는데, JPA는 이 같은 문제점을 보완해서 개발자 대신 적절한 SQL을 생성하고 데이터베이스를 조작해서 객체를 자동 매핑하는 역할을 수행한다.

 

ORM에서의 단점을 일부 해결하였는데, 데이터베이스는 상속관계를 지원하지 않는데 JPA는 이를 해결하였다.

예를 들어서 item이라는 table에 name과 price라는 column이 있다고 가정하자. 이를 상속하여서 나는 book이라는 table을 만들고 싶다면 item의 id를 book이 primary key로 상속받는 형식으로 해결한다.

 

JPA의 구성요소로는 javax.persistence 패키지로 정의된 API 그 자체가 있고, JPQL(Java Persistence Query Language) 그리고 객체관계 메타데이터로 구성된다고 한다.

 

JPA 기반의 구현체(ORM 프레임워크)는 대표적으로 세가지가 있다. (하이버네이트, 이클립스 링크, 데이터 뉴클리어스)

이 중에서도 하이버네이트를 제일 많이 사용한다.

하이버네이트

: 자바의 ORM 프레임워크로 JPA구현체 중 하나이다. Hibernate가 지원하는 메서드 내부에서는 JDBC API가 동작하고 있다.

 

HQL(Hibernate Query Language)이라 불리는 매우 강력한 쿼리 언어를 포함하고 있다.

 

HQL은 완전히 객체 지향적이며 상속, 다형성, 관계 등의 객체 지향의 강점을 사용할 수 있다.

 

HQL은 쿼리 결과로 객체를 반환하며 생성과 접근을 개발자가 원하는 대로 할 수 있다.

 

HQL은 페이지네이션과 동적 프로파일링 같은 기능을 제공한다고 한다.

 

JDBC(Java Database Connectivity)

JDBC는 DB에 접근할수 있도록 Java에서 제공하는 API이다. 모든 Java Data Access 기술의 근간이 되고, 모든 영속성컨텍스트의 프레임워크는 내부적으로 JDBC API를 사용한다고 보면된다.

 

Spring Data JPA

JPA를 편리하게 사용할 수 있도록 지원하는 스프링 하위 프로젝트 중 하나이다. 데이터베이스 CRUD 처리에 필요한 인터페이스를 제공하며, 하이버네이트의 엔티티 매니저를 직접 다루지 않고 리포지토리를 정의해 사용함으로써 스프링이 적합한 쿼리를 동적으로 생성하는 방식으로 데이터베이스를 조작한다. 이를 통해 하이버네이트에서 자주 사용되는 기능을 더 쉽게 사용할 수 있게 구현한 라이브러리이다.

 

Mybatis

ORM, JPA, Hibernate 이쪽과는 다른 방식으로 데이터베이스를 다룬다.

 

Mybatis는 SQL Mapper라는 개념을 사용하는 SQL Mapper는 자바 객체를 실제 SQL문에 연결해주어서 빠른 개발과 편리한 테스트 환경을 제공한다.

 

JDBC로 처리하는 부분 중 코드와 파라미터 설정 및 결과 연결(mapping)을 대신해준다.

(Mybatis의 예전 이름은 iBatis인데 Google Code로 이전되면서 이름이 바뀌었다.)

 

Mybatis vs JPA(ORM)

  • 영속 계층에서의 영속 프레임워크는 2개로 나눌 수 있는데 SQL Mapper와 ORM으로 나눌 수 있다.
  • ORM은 데이터베이스 객체를 자바 객체로 매핑함으로써 객체 간의 관계를 바탕으로 SQL을 자동으로 생성해준다.
    • 관계형 데이터베이스의 '관계'를 Object에 반영하자는 것이 목적이다
  • SQL Mapper는 SQL을 명시해주어야 한다.
  • JPA는 ORM 기술이고 MyBatis는 SQL Mapper의 한 종류이기 때문에 데이터베이스를 어떻게 다룰 것이냐에 따라 선택하면 될 것 같다

 

 

 

 

 

 

[참고] [JDBC] JDBC, JPA/Hibernate, Mybatis의 차이 - Heee's Development Blog

728x90
반응형

+ Recent posts