컴공생의 발자취

[내일배움캠프 50일차 TIL] 데이터베이스(H2, JDBC 드라이버, Query Mapper)및 MyBatis 본문

🤝 활동/내배캠TIL

[내일배움캠프 50일차 TIL] 데이터베이스(H2, JDBC 드라이버, Query Mapper)및 MyBatis

MNY 2024. 6. 27. 23:45
728x90
반응형
오늘의 진도
- AWS의 모든 것(All about AWS) 2주차 완강까지...
- JPA 심화 3주차 - 쿼리 코드 만들기(JpaRepository) 까지...


아.. 진짜 이게 무슨 소리야ㅠ 그래서 뭘 중점적으로 알고 있어야 하는 거지?
오늘의 학습, 코드카타, 오늘의 회고 이렇게 3개의 큰 틀로 나누어 정리할 것이다.

 

💡 오늘의 학습 키워드

- AWS의 모든 것(All about AWS) 2주차 -
MFA 추가하기

- JPA 심화 2주차 : 데이터베이스 다루기 -
데이터베이스 생성(H2)
트랜잭션
데이터베이스 Driver 동작 방식
JDBC 드라이버
Statement vs PreparedStatement
JDBC Template(Query Mapper)

- JPA 심화 3주차 : RawJPA 기본 -
MyBatis

 

MFA 추가하기

2024.06.27 - [🧡 AWS] - [AWS] MFA 추가하기 feat. 루트 사용자 ( + MFA 코드 2개? )

 

[AWS] MFA 추가하기 feat. 루트 사용자 ( + MFA 코드 2개? )

* 들어가기에 앞서서이제 사용자 추가했으면 MFA라는 것을 추가해야 한다고 하는데..아니 하다가 안되서 왜 이게 난 안 되지? 하고 한 30분 날려먹었다ㅠ - 목차 -0. MFA란?Setting. 언어 설정1. MFA 추

moonnight0.tistory.com

 


 

데이터베이스 생성(H2)

1. Server Mode - 배포 용도

  • 직접 엔진 설치
  • 애플리케이션과 상관없는 외부에서 DB엔진 구동
  • 데이터가 애플리케이션 외부에 저장되므로 애플리케이션을 종료해도 데이터가 사라지지 X

2. In-memory Mode - 테스트 용도

  • 엔진을 설치하지 않고 애플리케이션 내부의 엔진 사용
    * build.gradleapplication.properties 설정을 통해 실행 가능
  • 애플리케이션과 같이 DB 엔진 실행 및 종료
  • 데이터가 애플리케이션의 메모리에 저장되기 때문에 애플리케이션 종료시 데이터 소실

3. Embedded Mode - 개발 용도

  • 엔진을 설치하지 않고 애플리케이션 내부의 엔진 사용
    * build.gradleapplication.properties 설정을 통해 실행 가능
  • 애플리케이션과 같이 DB 엔진 실행 및 종료
  • 데이터가 애플리케이션 외부에 저장되므로 애플리케이션을 종료해도 데이터가 사라지지 X
Mode H2 다운로드 여부 실행 주체 DB 저장 위치 사용 용도
Server Mode O 외부 로컬(파일 시스템) 배포 용도
In-Memory Mode X 스프링 메모리 테스트 용도
Embedded Mode X 스프링 로컬(파일 시스템) 개발 용도

 

트랜잭션

: 데이터베이스의 상태를 변화시키기 위해서 수행하는 작업의 단위

문제가 발생시 그 전에 했던 변경을 아무일도 없던 것처럼 모두 되돌린다.

 

* 3가지 특성 (원자성, 일관성, 독립성)

1. 원자성(All or Nothing)

  : 트랜잭션이 데이터베이스에 모두 반영되던가, 아니면 전혀 반영되지 않아야 한다.

2. 일관성(Keeps Data Correct)
  : 트랜잭션의 작업 처리 결과는 항상 일관성이 있어야 한다.

3. 독립성(Independent)
  : 둘 이상의 트랜잭션이 동시에 실행되고 있을 경우 어떤 하나의 트랜잭션이라도, 다른 트랜잭션의 연산에 끼어들 수 없다.

 

* 트랜잭션 DCL

0. GRANT, REVOKE 

  : 접근 권한 설정하기
1. BEGIN( = START TRANSACTION) 

  : 새로운 트랜잭션 생성 및 시작하는 연산
2. COMMIT 

  : 하나의 트랜잭션이 성공적으로 끝났고, 데이터베이스가 일관성 있는 상태에 있을 때, 하나의 트랜잭션이 끝났다라는 것을 알려주기 위해 사용하는 연산
3. ROLLBACK 

  : 하나의 트랜잭션 처리가 비정상적으로 종료되어 트랜잭션의 원자성이 깨진 경우, 트랜잭션을 처음부터 다시 시작하거나, 트랜잭션의 부분적으로만 연산된 결과를 다시 취소시킨다. 

 

데이터베이스 Driver 동작 방식

1. 연결 초기화 : 요청 수신, 연결 설정
2. SQL 전송 및 실행 : SQL 명령 변환, 명령 처리
3. 결과 처리 : 결과 수신, 결과 전달
4. 연결 종료 : 연결 해제

 

* JDBC Driver Manager는 애플리케이션이 실행되고 있는 런타임 시점에.. 

  • Connection(연결)을 생성하여 쿼리를 요청할 수 있는 상태를 만들어 주고
  • Statement(상태)를 생성하여 쿼리를 요청하게 해주고
  • ResultSet(결과셋)을 생성해 쿼리 결과를 받아 수 있게 해준다.

 

JDBC(Java Database Connectivity) 드라이버

자바 애플리케이션에서 데이터베이스에 접근할 수 있도록 하는 API

 

* JDBC 드라이버 타입

  • 네 가지 유형(Type 1, 2, 3, 4)이 있으며, 각각의 특징과 사용 환경에 따라 선택. 
  • Type 4 드라이버(순수 자바 드리아버)가 가장 일반적으로 사용.

** JPA도 이 기술을 사용하여 구현되어 있다.

 

Statement vs PreparedStatement

* Statement

  • 장점 : executeQuery()나 executeUpdate()를 실행하는 시점에서 파라미터로 완성된 SQL문을 전달하기에 한 눈에 파악하기 쉽다.
  • 단점 : SQL문을 수행하는 과정에서 구문 분석을 수행하기 때문에 PreparedStatement에 비해 효율성이 떨어진다.

 

* PreparedStatement

  • Statement를 상속하고 있는 Interface
  • 내부적으로 Statement의 4단계(구문분석, 치환, 실행, 인출)과정 중 첫 번째 parse 과정의 결과를 캐싱하고, 나머지 3단계만 거쳐서 SQL문이 실행
  • 장점
    • 구분 분석(parse)의 결과를 캐싱해서 과정을 생략할 수 있으므로 성능이 향상
    • 변수 문자열 쿼리를 집어넣어 해킹하는 SQL Injection 방어

 

JDBC Template(Query Mapper)

* JDBC 로 직접 SQL을 작성했을때의 문제

  • SQL 쿼리 요청시 중복 코드 발생
  • DB별 예외에 대한 구분 없이 Checked Exception (SQL Exception) 처리
  • Connection, Statement 등.. 자원 관리를 따로 해줘야함
    • 자원 해제 안해주면 메모리 꽉차서 서버가 죽음

** 해결하기 위해 Persistence Framework 등장!

 

* Persistence Framework

  • SQL Mapper (Query Mapper) : JDBC Template, MyBatis
    • SQL 문과 객체(Object)의 필드를 매핑하여 데이터를 객체화
  • ORM : JPA, Hibernate
    • SQL Mapper을 포함하는 상위 단계

 

* RowMapper

: SQL Mapper 첫번째 주자로 JDBCTemplateRowMapper 탄생

  • 쿼리 수행 결과와 객채 필드 매핑
  • RowMapper 로 응답필드 매핑코드 재사용
  • Connection, Statement, ResultSet 반복적 처리 대신 해줌
  • 😵‍💫 But, 결과값을 객체 인스턴스에 매핑하는데 여전히 많은 코드가 필요함

 


 

MyBatis

: RowMapper가 가지고 있는 단점인 "반복되는 코드"를 줄이고 "함께있는 프로그램 코드와 쿼리 코드를 분리하여 관리"하고 싶은 니즈를 반영하여 탄생

 

* 탄생 이유

  • 반복적인 JDBC 프로그래밍을 단순화 하고 싶다
  • SQL 쿼리들을 XML 파일에 작성하여 코드와 SQL을 분리하고 싶다.

 

* MyBatis 특징

  • jdbc로 처리하는 코드의 설정(Connection) 부분을 줄이고 실제 sql문에 연결함으로서 빠른 개발이 가능(SQL Mapper 특징)
  • map 인터페이스(또는 클래스)와 SQL 쿼리와 ResultSet 매핑을 위한 xml 및 annotation을 사용
  • 다른 방식에 비해 객체 자체보다 쿼리에 집중

SQL Mapper - DB 데이터 연동 구조

 

* 한계점

  • SQL 직접 작성은 피곤(DB 기능에 종속적)
  • 테이블마다 비슷한 CRUD 반복, DB 타입 및 테이블에 종속적

 

* MyBatis의 동작

(1) ~ (3)은 응용 프로그램 시작시 수행되는 프로세스입니다.

(1) 응용 프로그램이 SqlSessionFactoryBuilder를 위해 SqlSessionFactory를 빌드하도록 요청합니다.

(2) SqlSessionFactoryBuilder는 SqlSessionFactory를 생성하기 위한 Mybatis 구성 파일을 읽습니다.

(3) SqlSessionFactoryBuilder는 Mybatis 구성 파일의 정의에 따라 SqlSessionFactory를 생성합니다.

(4) ~ (10)은 클라이언트의 각 요청에 대해 수행되는 프로세스입니다.

(4) 클라이언트가 응용 프로그램에 대한 프로세스를 요청합니다.

(5) 응용 프로그램은 SqlSessionFactoryBuilder를 사용하여 빌드된 SqlSessionFactory에서 SqlSession을 가져옵니다.

(6) SqlSessionFactory는 SqlSession을 생성하고 이를 애플리케이션에 반환합니다.

(7) 응용 프로그램이 SqlSession에서 매퍼 인터페이스의 구현 개체를 가져옵니다.

(8) 응용 프로그램이 매퍼 인터페이스 메서드를 호출합니다.

(9) 매퍼 인터페이스의 구현 개체가 SqlSession 메서드를 호출하고 SQL 실행을 요청합니다.

(10) SqlSession은 매핑 파일에서 실행할 SQL을 가져와 SQL을 실행합니다.

 

  • SqlSession Factory Builder (1), (2), (3)
    • MyBatis 설정 파일을 읽어와서
    • 설정정보 기반으로 SqlSession Factory 를 생성하는 빌더 객체
  • MyBatis Config File (2)
    • 매핑해줄 객체가 들어있는 패키지 경로와
    • Mapping File 목록을 지정해주는 설정 파일
  • SqlSession Factory (3), (5), (6)
    • 설정에 맞게 SqlSession 을 생성하여 들고있는 객체
  • SqlSession (6), (7), (9), (10)
    • Mapping File 에서 쿼리를 조회해서 쿼리를 수행하고 응답을 받아올 수 있는 세션 객체
  • Mapper Interface (8), (9)
    • DB 에서 조회하는 객체와 Java 프로그램의 객체간에 인터페이스를 정의하는 객체
  • 방법1. Dao 클래스 정의
    • SqlSession 를 직접적으로 사용하는 방법
    • SqlSession 멤버 변수로 사용하며 쿼리파일 수행 요청
    • 장점
      • 쿼리문 실행 전에 넣어줄 매개변수와 쿼리 결과값의 변형을 정의할 수 있다.
      • Namespace를 내 마음대로 둘 수 있다.
      • .xml 파일의 쿼리문 id와 mapper 메소드명을 일치시킬 필요가 없다.
    • 단점
      • Sqlsession 객체를 주입받아야 하며, 쿼리문 실행 시 항상 호출해야 한다.
      • 쿼리문 호출 시 sqlsession에 .xml 파일의 namespce와 쿼리문 id를 매개변수로 넘겨야한다.
// UserDao.java
import org.apache.ibatis.session.SqlSession;
import org.springframework.stereotype.Component;

import com.thesun4sky.querymapper.domain.User;

@Component
public class UserDao {

  // SqlSession 멤버 변수로 사용하며 쿼리파일 수행 요청
  private final SqlSession sqlSession;

  public UserDao(SqlSession sqlSession) {
    this.sqlSession = sqlSession;
  }

  public User selectUserById(long id) {
    return this.sqlSession.selectOne("selectUserById", id);
  }

}

 

    • SqlSession 를 간접적으로 사용하는 방법
    • ibatis 에서 구현해주는 org.apache.ibatis.annotations.Mapper 어노테이션을 사용하면 sqlSession 를 사용하여 자동으로 호출해줌
    • 장점
      • 메소드의 내부 구현이 불필요하다.
      • Sqlsession 객체 주입이 불펼요하다.
      • .xml 파일의 쿼리문 id와 mapper 메소드 명이 일치한다.
    • 단점
      • .xml의 Namespace가 실제 Mapper.java 위치를 가르켜야 한다.
      • 메소드 내부 정의가 불가능하다.방법2. Mapper Interface 정의
// UserMapper.java
@Mapper
public interface UserMapper {

  User selectUserById(@Param("id") Long id);

}

 

  • Mapping File (10)
    • SqlSession 가 실행하는 쿼리가 담긴 파일
    • 정의된 인터페이스에 기반해서 수행할 쿼리를 담아두고
    • 쿼리 수행결과를 어떤 인터페이스 매핑할지 정의해놓은 파일
<!-- UserMapper.xml -->
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.thesun4sky.querymapper.mapper.UserMapper">
    <select id="selectUserById" resultType="User">
        select id, name from users where id = #{id}
    </select>
</mapper>

 


코드 카타

* 프로그래머스로 진행

 

  • 알고리즘
    • 없음
  • SQL
    • 자동차 대여 기록에서 대여중 / 대여 가능 여부 구분하기
    • 년, 월, 성별 별 상품 구매 회원 수 구하기

 


오늘의 회고

  • 12시간 중 얼마나 몰입했는가?

오전에는 팀원들과 이야기 한 후 튜터님이랑 대화하고 개인 강의 조금 듣고

점심 먹고 나서는 매니저님이랑 대화하고 실시간 강의랑 개인 강의 듣고

저녁 먹고.. 강의 조금 보다가 팀원들과 이야기 했더니 하루 뚝딱!

 

  • 오늘의 생각

아.. JPA 강의가 심상치 않다...

뭔가.. 뭔가가 많긴 한데...

그래서 뭐가 중요하고 내가 알아야 할 것은 무엇이며

실습에서 적용은 어떻게 해야하는 것인가............ 그것이 문제로다ㅠ

 

  • 내일 학습할 것은 무엇인지

JPA, AWS 강의 완강하기!!!

이거 작성하고도 새벽에 좀 보면 내일 다 들을 수 있지 않을까?

할 수 있다! 화이팅~~~ 🏃‍♀️🏃‍♂️

 

728x90
반응형