728x90
반응형

Transaction의 컨텍스트에서 Rollback 은 문제가 발생할 경우 Transaction중에 데이터베이스에 대한 변경 내용을 실행 취소하는 프로세스이다.

 

Transaction은 일련의 데이터베이스 작업을 하나의 원자 단위로 그룹화하는 방법이다.즉,  연산들을 전부 실행하든지 전혀 실행하지 않는 All or nothing 방식이다.

이 개념은 Transaction내에서 수행된 모든 변경사항이 단일 단위로 commit(데이터베이스에 저장)되거나 rollback(실행 취소)된다는 것이다. Transaction으로 인한 하나의 묶음 처리가 시작되기 이전의 상태로 되돌린다.

 

예를 들어, 한 은행 계좌에서 다른 은행 계좌로 돈을 송금하는 시나리오를 가정해보자. 거래가 차변영업(한 계좌에서 돈을 제거하는 것)과 신용영업(다른 계좌에 돈을 추가하는 것)을 모두 포함하는 경우, 데이터베이스는 두 가지 영업이 모두 완료되었는지 또는 둘 다 완료되지 않았는지 확인해야 한다.

 차변 작업은 성공했지만 신용 작업이 어떤 이유로 실패하면 rollback 작업은 차변 작업을 취소하여 데이터베이스의 원래 상태를 효과적으로 복원한다.

 

rollback 작업은 일반적으로 Transaction중에 오류나 예외가 발생하거나 사용자 또는 응용 프로그램에 의해 Transaction이 명시적으로 롤백될 때 트랜잭션 관리 시스템에 의해 수행된다.

또한 비정상 종료되었다면 자동으로 rollback이 된다.

728x90
반응형

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

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

보통 로그인을 구현할 때, 인증받기 위해 Token 또는 Session을 사용한다. 두 가지 방법의 차이점을 알아보겠다.

Token

토큰은 인증 및 인가에 대한 보다 현대적인 접근 방식이다.

토큰은 일반적으로 Local Storage나 cookie와 같은 클라이언트 측 스토리지 메커니즘에 저장되며, 각 요청과 함께 서버로 전송된다. 토큰은 Stateless 즉, 서버는 클라이언트 세션에 대한 정보를 저장할 필요가 없다.

이를 통해 서버 확장(Scale Up)이 쉬워져 보다 분리된 아키텍처가 가능하다. 토큰은 쉽게 취소되고, 도난의 영향을 덜 받기 때문에 세션보다 안전하다.

쉽게 취소된다는 의미는 서버에 의해서 언제든지 토큰을 무효화할 수 있다는 것이다. 만약 유저가 로그아웃을 하면 서버는 그냥 토큰을 취소하면 되는 것이다.

Session

세션은 클라이언트 상태에 대한 정보를 서버에 저장한다.

즉, 서버는 모든 활성 세션의 레코드를 유지하고 세션 데이터의 스토리지를 관리해야 한다.

세션은 구현이 간단하고 기존 웹 애플리케이션에서 자주 사용된다. 그러나 토큰만큼 안전하지 않기 때문에 세션 ID가 도난당한 경우 세션은 보안에 취약할 수 있다.

일반적으로 토큰은 확장성과 보안이 향상되기 때문에 현대 웹 애플리케이션에 더 나은 옵션이다. 다만 세션은 여전히 일반적으로 사용되고 있으며 기존 웹 애플리케이션 또는 단순 인증 요건을 가진 애플리케이션에게는 적절한 선택사항이 될 수 있다.

 

그럼 Token을 Cookie와 Local Storage 중 어디에 저장하는 것이 좋을까?

LocalStorage와 Cookie 중 어느 쪽을 선택할지는 애플리케이션의 특정 요건에 따라 달라진다.

Local Storage

로컬 스토리지는 클라이언트 측 스토리지 메커니즘으로 클라이언트 디바이스에 데이터를 저장할 수 있다.

로컬 스토리지에 저장된 데이터는 여러 탭 및 창을 통해 액세스할 수 있으며 사용자가 브라우저를 닫더라도 삭제되지 않는다.

로컬 스토리지는 다른 도메인에서 자바스크립트로 액세스할 수 없기 때문에 쿠키보다 안전합니다.

Cookie

쿠키는 브라우저에 의해 클라이언트 장치에 저장되는 작은 텍스트 파일이다. 쿠키는 클라이언트 세션에 대한 정보를 저장하는 데 사용할 수 있으며 요청 시마다 서버에서 쉽게 액세스할 수 있다. 쿠키의 크기는 보통 4KB로 제한되어 있으며, 적절하게 관리하지 않으면 보안 위험에 취약할 수 있다.

일반적으로 로컬 스토리지는 여러 세션에 걸쳐 유지해야 하는 대량의 데이터 또는 데이터를 저장하기 위한 더 나은 옵션이다. 쿠키는 클라이언트 세션에 필요한 소량의 데이터를 저장하는 데 최적의 선택사항이며, 각 요청과 함께 서버로 쉽게 전송할 수 있다.

 

결국에 다른 특이 사항이 없는 이상 Token을 사용하여 Local Storage로 저장하는 방법이 좋은 것 같다.

728x90
반응형

'CS' 카테고리의 다른 글

[네트워크] TCP  (3) 2023.11.22
[네트워크] UDP  (0) 2023.11.21
[네트워크] DNS  (0) 2023.11.21
[데이터베이스] 데이터베이스 트랜잭션, 회복  (0) 2023.10.12
728x90
반응형

데이터베이스 로깅이란 데이터베이스의 모든 변화 레코드를 가지고 있는 것이고, 데이터베이스의 회복이란 데이터베이스의 transaction들을 수행하는 도중 장애로 인해 손상된 데이터베이스를 손상되기 이전으로 복구시키는 작업이다. 이 정보는 log file로 저장되어 있고 데이터베이스 transaction의 기록으로 역할을 한다. 실패했을 시, 로그 파일은 데이터베이스를 일관된 상태로 회복하기 위해 log file을 사용한다.

 

데이터베이스가 로깅을 이용하여 데이터베이스를 회복하는 과정은 다음과 같다

  1. 데이터베이스는 전체 백업을 수행하거나 정기적인 incremental 백업을 수행하여 백업된다.
  2. 데이터베이스에서 transaction이 commit되면, log file에 해당 transaction에 의해 변경된 내용을 설명하는 항목이 생성된다. 이 정보는 장애 발생 시 데이터베이스를 복구하는 데 사용된다.
  3. 만약 실패가 일어나면, 데이터베이스는 시스템이 종료되고 복구 프로세스가 시작된다.
  4. 복구 프로세스는 로그 파일을 읽고 로그 파일에 포함된 정보를 사용하여 마지막 commit 당시의 상태로 데이터베이스를 recreate하는 것으로 시작된다. 여기에는 오류가 발생했을 때 완전히 완료되지 않은 transaction의 실행 취소가 포함된다.
  5. 복구 프로세스가 완료되면 데이터베이스가 다시 시작되고 정상적인 작업을 재개할 수 있다.

로그 파일은 데이터베이스의 저장위치와 분리되어서 실패했을때 잃어버리지 않아야 한다. 추가적으로 log file은 정기적으로 백업되어서 위기 상황을 막아야 한다.

 

즉, 데이터베이스 로깅은 데이터베이스 시스템에서 데이터 무결성 및 가용성을 보장한다.

728x90
반응형

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

[DevOps] 쿠버네티스 환경구축  (0) 2023.03.29
[DevOps] 도커  (0) 2023.03.21
가상메모리(Virtual Memory)  (0) 2023.02.17
Transaction과 Rollback  (0) 2023.02.14
728x90
반응형

https://www.acmicpc.net/problem/1062

 

1062번: 가르침

첫째 줄에 단어의 개수 N과 K가 주어진다. N은 50보다 작거나 같은 자연수이고, K는 26보다 작거나 같은 자연수 또는 0이다. 둘째 줄부터 N개의 줄에 남극 언어의 단어가 주어진다. 단어는 영어 소문

www.acmicpc.net

[문제 정의]

이 문제는 n개의 단어가 주어지면 k개의 알파벳을 배워서 몇 개나 읽을 수 있는지 판단하는 것이다. 근데 조건에서 단어는 무조건 앞에는 anta로 시작되고 끝은 tica로 끝난다.

 

해당 조건에서 알 수 있는 사실은 a, c, i, n, t는 최소한 배워야 단어를 읽을 수 있다는 사실이다. 만약에 k가 5보다 작으면 a,c,i,n,t를 다 배우지 못하기 때문에 판단하기도 전에 제외된다. 

[풀이]

먼저, 나는 alreadyLearned변수에 a,c,i,n,t를 집합으로 정의하였다. 그리고 단어를 입력받을때 단어는 무조건 anta로 시작하고 tica로 끝난다고 하였으므로 해당 단어를 잘라서 나머지 부분만 letter에 저장하여 letters에 넣었다. 그리고 toLearnList라는 변수에는 배워야하는 단어들을 다 추가하였다.

 예를 들어 단어가 antacbtica와 antaztica라고 한다면 letter는 [c,b], [z]가 들어가고 toLearnList에는 c,b,z,를 모두 합한 집합인 {c,b,z}가 들어간다. 

 

그리고 나는 조합을 이용하여서 toLearnList에서 k-5개를 뽑았다. k-5개를 뽑은 이유는 이미 alreadyLearned에 있는 5개는 벌써 배웠다고 가정하는 것이다.

 

그래서 뽑은 경우의 수를 하나씩 테스트해서 letter에 있으면 continue를 하고 없다면 break를 하는 식으로 반복문을 빠져나와서 조합으로 뽑은 경우의 수마다 몇 개의 단어를 배울 수 있는지 answer에 모두 넣는다. 그래서 answer배열 중 제일 큰 수가 제일 많이 배울 수 있는 경우이므로 해당 값을 출력한다.

 

 예를 들어 letters로 antartica, antahellotica, antartica를 입력 받은경우 나머지 변수들은 아래와 같다.

[['r'], ['h', 'o', 'e', 'l'], ['r']] # letters
['e', 'h', 'o', 'r', 'l'] # toLearnList
[('o',), ('l',), ('h',), ('e',), ('r',)] # checks

[놓친 부분]

처음에 계속 틀렸었는데 이유를 찾지 못하였다. 같은 스터디원에게 도움을 요청한 결과 combination을 완벽하게 사용하지 못한 것이 이유였다.

 

1C3과 같은 경우는 combination에서 처리를 하지 못하기 때문에 (1개에서 3개를 뽑는 경우는 되지 않는다) 해당 코드는 오류처리를 해주었어야 하는데 놓쳤었다.

[정답]

import sys

input = sys.stdin.readline
from itertools import combinations


def antarctica(letters, toLearnList):
    # print(letters) [['r'], ['h', 'o', 'e', 'l'], ['r']]
    # print(toLearnList) ['e', 'h', 'o', 'r', 'l']
    if len(toLearnList)<k-5:
        print(len(letters))
    else:
        checks = list(combinations(toLearnList, k - 5))
        # print(checks) # [('o',), ('l',), ('h',), ('e',), ('r',)]
        answer = []
        for check in checks:
            ans = len(letters) # 처음엔 다 배울 수 있다고 가정하고 못배우는 걸 뺴는 방법으로
            check = list(check) # 필요한지 잘 모르겠음
            for letter in letters:
                if len(letter) > k - 5:  # 배워야 되는 숫자가 더 많음
                    ans -= 1
                    continue
                elif len(letter) == 0:  # 이미 다 배움
                    continue
                else:
                    for i in range(len(letter)):
                        if letter[i] in check:  # 조합으로 k-5만큼 선택한 배열 안에 있는 경우
                            continue  # 계속 진행
                        else:
                            ans -= 1  # 없을 경우 이 단어는 이 조합으로는 일단 만들 수 없다
                            break
            answer.append(ans)
        print(max(answer))


n, k = map(int, input().split())
alreadyLearned = {'a', 'c', 'i', 'n', 't'} # 무조건 a,c,i,n,t는 배워야 함. 최소 5개
letters = []  # 가르치는 단어들
toLearnList = set()  # 배워야하는 글자들
for i in range(n):
    letter = set(list(input())[4:-5]) - alreadyLearned  # 입력받은 단어를 앞뒤 다 짜르고 이미 배운거 빼기
    toLearnList.update(letter) # 배워야하는 곳에 추가하기
    letters.append(list(letter))
if k < 5:
    print(0)  # 아무것도 배울 수 없다.
else:
    antarctica(letters, list(toLearnList))

[다른 풀이]

스터디원의 다른 풀이 중 비트마스킹을 사용하는 풀이가 있었다. (다시 봐도 생각해내기는 어려울것 같긴하다..)

 

비트 마스킹이란 컴퓨터 내부적으로 모든 자료는 이진수로 표현하기 떄문에 이런 특성을 이용해서 이진수 표현을 자료구조로 사용하는 기법을 비트 마스킹이라고 한다. 

 

비트마스크를 이용하면 집합을 쉽게 표현할 수 있다. 집합에 원소를 추가, 삭제하는 연산을 굉장히 빠르게 할 수 있다. 

 

원소의 개수가 N인 집합이 있다고 하면, 각각의 원소를 0부터 (N-1)번까지 번호를 부여하고, 번호에 해당하는 비트가 1이면 원소가 포함, 0이면 원소가 불포함이라고 한다면 집합을 비트를 이용해 표현할 수 있다.

 

이전 풀이는 집합으로 단어를 저장했는데 이번에는 이진법으로 알파벳을 포함하는지 아닌지를 저장하는 차이이다. 

 

메모리를 훨씬 줄일 수 있어서 더 효율적인 코드인것 같다.

참고 :  https://coder38611.tistory.com/136

 

from itertools import combinations
n, k = map(int, input().split())
if k < 5:
    print(0)
else:
    k -= 5
    alreadyLearned = {'a', 'n', 't', 'i', 'c'}
    input_chars = []
    alpha = {ky: v for v, ky in enumerate(
        (set(map(chr, range(ord('a'), ord('z')+1))) - alreadyLearned))} # 이미 배운것은 뺴줌
    cnt = 0
    for _ in range(n):
        tmp = 0
        for c in set(input())-alreadyLearned:
            tmp = tmp | (1 << alpha[c])
        input_chars.append(tmp)
    power_by_2 = (2**i for i in range(21))
    for comb in combinations(power_by_2, k):
        test = sum(comb)

        ct = 0
        for cb in input_chars:
            if test & cb == cb:
                ct += 1

        cnt = max(cnt, ct)
    print(cnt)

 

 

 

728x90
반응형
728x90
반응형

https://www.acmicpc.net/problem/17609

 

17609번: 회문

각 문자열이 회문인지, 유사 회문인지, 둘 모두 해당되지 않는지를 판단하여 회문이면 0, 유사 회문이면 1, 둘 모두 아니면 2를 순서대로 한 줄에 하나씩 출력한다.

www.acmicpc.net

[문제 정의]

이 문제는 회문을 판단하는 것 이외에 유사 회문이라는 것을 정의하였다. 회문은 앞뒤가 똑같은 단어이고, 유사 회문은 회문이 아닐경우 단어 하나만 제외하면 회문이 되는 단어를 말한다. 그럼 경우가 3가지를 구분하여 정답을 출력해주면 되는 문제였다.

 

[풀이]

1. [잘못된 풀이] : 처음에 생각한 풀이는 문자열의 맨 앞 단어와 맨 뒤의 단어를 없애버리면서 하나씩 고려하는게 좋다고 생각하였다. 그래서 맨 앞의 단어와 맨 뒤의 단어가 같으면 파이썬 list에 있는 pop함수를 이용하여 제외시켰다. 

그리고 만약 앞 뒤의 단어가 다르다면 경우를 2개로 나눈다. 남은 단어의 젤 앞을 제외하는 경우와 젤 뒤를 제외하는 두 개의 case로 나누어서 해당 단어를 다시 회문인지 아닌지 판단하여 해당 단어가 회문이면 결국에 처음에 제공된 문자열은 유사회문인 것이다. 

import sys
input = sys.stdin.readline
T = int(input())
letterlist = []
answers = []
for i in range(T):
    letter = list(input())
    letterlist.append(letter[:-1])
for letter in letterlist:
    left = 0
    right = len(letter) - 1
    answer = 2
    while True:
        if letter[left] == letter[right]:
            letter.pop(right)
            letter.pop(left)
            right = len(letter) - 1
            if len(letter) == 0 or len(letter) == 1:
                answer = 0
                break
        elif letter[left] != letter[right]: # 다른 경우
            temp1 = letter[left + 1:right + 1]
            if temp1[:] == temp1[::-1]:
                answer = 1
                break
            else:
                temp2 = letter[left:right]
                if temp2[:] == temp2[::-1]:
                    answer = 1
                break
    answers.append(answer)
for answer in answers:
    print(answer)

위의 풀이는 예제는 맞지만, 시간 초과가 나는 코드이다. 어느 부분이 문제인지 몰랐었는데 pop이 문제였다. 맨 앞의 단어를 pop하는 경우는 시간 복잡도가 O(1)이라서 괜찮았지만 문자열 맨 뒤의 단어를 pop하는 경우는 O(n)이 될 수 있어서 시간초과가 나는 것이였다.

그래서 해당 코드를 비슷하게 유지하되 pop시키지 않고 비교만 하는 코드로 바꾸었다.

 

[정답]

import sys
input = sys.stdin.readline

T = int(input())
letterlist = []
answers = []

for i in range(T):
    letter = list(input())
    letterlist.append(letter[:-1])


for letter in letterlist:
    left = 0
    right = len(letter) - 1
    answer = 2
    while True:
        if letter[left] == letter[right]:
            letter.pop(right)
            letter.pop(left)
            right = len(letter) - 1
            if len(letter) == 0 or len(letter) == 1:
                answer = 0
                break
        elif letter[left] != letter[right]: # 다른 경우
            temp1 = letter[left + 1:right + 1]
            if temp1[:] == temp1[::-1]:
                answer = 1
                break
            else:
                temp2 = letter[left:right]
                if temp2[:] == temp2[::-1]:
                    answer = 1
                break
    answers.append(answer)

for answer in answers:
    print(answer)
728x90
반응형
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
반응형
728x90
반응형

Gradle

Task들을 자동화 시켜 주는 Build Tool이다.

→ Task : Compile, Test, Packaging, Deploy, Run

안드로이드에서의 Task들은 다음과 같다.

Compile : Java나 Kotlin 파일을 바이트 코드로 변환해주는 작업

Test : 어플리케이션이 제대로 동작할지에 대한 Test를 하는 작업

Packaging : 코드를 패키징해 aab파일이나 apk 파일로 만들어주는것

Deploy & Run : 코드를 어플리케이션으로 패키징해서 실제 기기에 넣어서 실행할 수 있도록 만들어 주는 것.

스프링 → Compile과 Test는 안드로이드와 동일. 패키징은 jar나 war파일로 만들어준다.

Deploy&Run은 만들어진 스프링을 돌려 서버를 실행해주는 것을 뜻함.

장점

  1. 직관적인 코드와 자동완성
  2. 다양한 Repository 사용 가능
  3. 각 작업에 필요한 라이브러리들만을 가져오는 작업

implementation : 라이브러리를 가져오는 것을 뜻한다.

Groovy언어로도 사용할 수 있는데 Groovy는 자바 문법이랑 유사하고 Gradle Wrapper를 이용하면 Gradle이 설치되지 않은 시스템에서도 프로젝트를 빌드할 수 있다.

728x90
반응형
728x90
반응형

위와 같은 오류가 발생하였다.

 

발생한 상황은 다음과 같다.

게시판 서비스를 만드는데 게시글과 댓글을 mapping 해주기 위해서 댓글(article_comment)에 FK로 article_id 열을 넣어야 했다. 이 문제는 해당 SQL문을 실행할 때, article_id에 해당하는 게시물이 없어서 생기는 문제였다.

 

게시글의 id를 확인하여 존재하는 id를 넣어주면 된다. 

728x90
반응형

+ Recent posts