JAVA/ORM

[JSP] MyBatis 적용 (ORM/ 어노테이션 없이)

읽히는 블로그 2024. 7. 29. 01:08

▤ 목차

     
     
     

    ✔ ORM (Object Relation Mapping)

    ✏️ 개념

    ORM이란 객체와 DB의 테이블을 Mapping 시켜 RDB 테이블을 객체지향적으로 사용할 수 있게 해주는 기술이다.

    관계형 데이터베이스 시스템 (MySQL, PostgreSQL..)은 테이블과 열로 구성된 데이터를 사용한다.
    데이터는 객체이며 독립된 데이터와 독립된 함수를 지닌다.
    객체지향 프로그래밍 언어( JAVA .. )는 클래스와 객체로 데이터를 구성한다.
    RDB 테이블은 객체지향적 특성(상속, 다형성 .. )* 등이 없어서 JAVA와 같은 객체지향적 언어로 접근하는 것이 쉽지 않다.
    이러한 (객체 모델과 관계형 모델 간의) 불일치를 해결하기 위해서 ORM을 사용하면 보다 객체지향적으로 RDB를 사용할 수 있다.
     
    객체와 관계형 데이터베이스 간의 데이터를 변환하고 매핑하는 기술이다.
    ORM을 통해 객체 간의 관계를 바탕으로SQL을 자동으로 생성하여 불일치를 해결한다.
     
    ORM은 객체와 데이터베이스 테이블 간의 매핑 규칙을 정의하고 개발자가 SQL 쿼리보다 객체에 집중할 수 있도록 해준다.
    객체 지향적인  코드로 인해 더 직관적이고 비즈니스 로직에 더 집중할 수 있게 한다.

    • 선언문, 할당, 종료와 같은 부수적인 코드가 없거나 급격하게 줄어든다.
    • 각 객체에 대한 코드를 별도로 작성하기에 코드의 가독성이 높아진다.
    • 절차적, 순차적 접근이 아닌 객체 지향적인 접근으로 생산성이 증가한다.
    • 재사용성 및 유지보수의 편리성이 증가한다

     

    더보기

    객체지향적 특성

     

     
     

    💻 ORM의 목적

    • 추상화 
      데이터베이스 구조의 복잡성을 숨기고 객체 모델을 단순화하여 개발자가 직관적으로 데이터를 다룰 수 있게 한다.
    • 유지보수성 향상
      데이버베이스 스키마 변경이나 쿼리 수정 시 ORM이 자동으로 이를 처리해주기에 개발자가 코드를 일일히 수정하지 않아도 된다. 즉, DB 변경시에도 코드 변경을 최소화하며 독립성이 보장된다.
    • 성능 최적화
      ORM은 내부적으로 데이터베이스 접근을 최적화하여 빠른 데이터 처리를 가능하게 한다. 캐싱, 지연로딩 등 성능 튜닝을 지원한다.
    • 코드 재사용
      ORM을 사용하면 데이터베이스 접근 관련 코드를 재사용할 수 있어 개발 생산성을 높이고 코드 중복을 줄일 수 있다.

     

    👏 중요

    대표적인 ORM 프레임워크로는 Java에서는 Hibernate, Python에서는 Django의 ORM, SQLAlchemy 등이 있다.
    * JAVA에서 사용하는 대표적인 ORM 으로 JPA와 Hiberante가 있다.
    JPA가 등장하기 전에 Mybatis라는 Object Mapping 기술을 사용하였는데, Mybatis는 JAVA클래스 코드와 직접 작성한 SQL코드를 mapping 시켜줘야한다.
     
     


     
     
     

    ✔ MyBatis

     

    📎 개념

    MyBatis는 ORM 프레임워크의 하나로 볼 수 있다. (사실 조금 애매하다. 이유는 아래에)
    데이터베이스와의 상호작용을 위한 SQL 매핑을 중심으로 설 프레임워크이다.
    MyBatis는 sql을 직접 작성하고 관리한다.
    SQL 매핑을 XML이나 어노테이션을 통해 설정하여 객체와 데이터베이스 간의 매핑을 처리한다.
     
     

    📌 주요 특징

    특징설명
    SQL 컨트롤개발자가 SQL을 직접 작성하고 관리할 수 있다.. 복잡한 쿼리나 특정 데이터베이스 특화 기능을 사용할 때 유리하다.
    객체 매핑SQL 결과를 자바 객체에 매핑하는 기능을 제공한다. MyBatis의 ResultMap을 사용하여 데이터베이스의 테이블과 자바 객체의 필드를 매핑할 수 있다.
    다양한 DB 지원MyBatis는 대부분의 주요 데이터베이스와 호환된다. JDBC 드라이버를 통해 다양한 데이터베이스 시스템과 연동할 수 있다.
    유연성XML 기반의 SQL 매핑 파일을 사용하여 SQL과 자바 코드를 분리할 수 있다.
    SQL의 변경이 필요하면 소스코드 변경 없이 XML 파일만 수정하여 관리할 수 있다..

     
     
     

    🤔 MyBatis가 ORM으로 정의되는게 맞나?

    ORM(Object - Relational Mapping)프레임워크로 정의되는게 맞는지 논란이 있다.
    그 이유는 MyBatis가 전통적인 ORM 프레임워크와 다른 점이 있다.

     MyBatis전통 ORM
    SQL 중심 접근SQL을 직접 작성하고 관리하는 방식을 선호.
    매핑은 XML이나 어노테이션을 통해 수행된다.
    SQL은 개발자가 직접 접근하고 제어할 수 있다.
    자동으로 SQL을 생성하고 관리한다. 
    객체 매핑의 제한성객체와 데이터베이스 테이블 간의 매핑을 처리할 수 있다. 매핑이 완전한 객체 지향적인 방식으로 이루어지지 않을 수 있다.
    직접 SQL을 작성하여 객체와 데이터베이스 간의 매핑을 수행한다.
    객체의 상속, 관계 매핑 등 자동으로 처리한다.
    레벨한 기능 제공객체와 데이터베이스 간의 매핑 이외에도 트랜잭션 관리, 캐시 관리 등의 기능을 제공한다.객체 그래프 탐색과 같은 고급 기능들은 제한적일 수 있다.
    쿼리 및 성능 최적화개발자가 직접 SQL을 적성하므로 성능 최적화나 복잡한 쿼리 작성에 있어서 유연성을 제공한다.
    하지만 개발자가 SQL을 이해하고 관리해야하는 부담을 가지게 할 수 있다.
     

     
     

    👏 중요

    MyBatis는 데이터베이스 접근을 위한 강력한 도구이다.
    SQL을 중심으로 개발하고자 하는 경우 유용한 것같다. 
    개발자가 "직접"하는 것이 많아 개발자의 깊은 이해가 필요하지만 그만큼 자유도(?)가 높다
    SQL 매핑을 XML 파일로 정의하면서도 다양한 설정 조작을 통해 캐싱, 트랜잭션 관리 등을 개발자가 조정할  수 있다.
     
    SQL이 자동으로 된다는 말이 달콤하게 들리는 것같다. 자동화에 익숙해지면 편하지만 익숙해지면 아는 SQL도 잊어버릴 것 같아 경계해야겠단 생각을 한다.
    그러면서도 현재 추세는 JPA와 Hibernate로 가고있다는 것을 알고있다.
    객체와 관계형 DB간의 매핑을 자동으로 처리하는 기능을 제공하기에 생산성 향상을 제공하기도 하고
    대규모 프로젝트에서는 JPA와 Hibernate 등의 ORM 프레임워크가 선호되는 경우가 많다고 한다.
     
     


     
     
     

    ✔주요 코드와 개념

    전반적인 흐름은 이러하다

    🛢️MyBatis 설정 파일

    MyBatis 프레임워크에 사용되는 xml 형식의 설정 파일이다.
    MyBatis는 SQL 매핑을 쉽게하기 위해 자바 객체와 SQL문 사이의 자동 매핑을 지원하는 프레임워크이다. 
    데이터베이스 연결 정보와 sql 매퍼 파일 위치 등을 설정한다.
    MyBatis는 이 설정을 기반으로 데이터베이스와의 연결을 설정하고 sql 쿼리를 실행하여 자바 객체와 매핑을 한다.
    이 파일을 통해 MyBatis를 사용하여 데이터베이스 접근 계층을 구성할 수있다. 

     

    🖇️ DOCTYPE 선언과 DTD

    이 부분은 XML 파일이 사용하는 DTD(Document Type Definition)을 정의한다.
    여기서 MyBatis 3.0의 설정파일을 위한 DTD를 참조하겠다는 의미이다.
    xml파일의 구조와 요소들이 어떻게 정의되는지 명시한다.
     

    더보기

    DTD(Document Type Definition)

    xml문서의 구조와 유효성을 정의하는 문서이다.

    주로 xml 문서가 지켜야 할 요소(element)와 속성(attribute)의 정의를 포함하고 있다.

    구조적인 제약을 명시해서 xml문서가 올바르게 작성되었는지 검증하는데 사용된다.

     

    주요 역할 및 특징

    - DTD는 XML 문서가 어떤 요소를 퐆함할 수 있고 각 요소의 순서와 계층 구조를 정의한다.

    - DTD는 XML 문서에 사용될 요소(element)와 그 요소들이 가질 수 있는 속성을 명시한다.

    -xml문서의 구조를 일반화해서 다양한 문서에서 재사용할 수 있다. 공통된 구조를 한곳에 정의해 관리할 수 있다.

     

     

    🖇️ < configuration >

    MyBatis의 설정 파일의 최상위 요소이다. 설정의 시작을 나타낸다.
     

    🖇️ < properties >

    외부 프로퍼티 파일을 로드해서 설정값을 외부에서 관리 할 수록 있도록 한다.

    ${driver}, ${url}, ${username}, ${password}와 같이 플레이스홀더를 사용하여 실제 값은 db.properties 파일에서 가져온다.

    ** 플레이스 홀더?
    설정 파일이나 코드에서 변수의 값을 동적으로 삽입할 수 있게 해주는 표현이다.
    xml에서 주로 ${..} 형식으로 표현된다.
    - 설정 파일에서변수의 값을 외부에서 제공된 값으로 쉽게 변경할 수 있다. 즉, 유지보수성을 높이는데 도움이된다.
    - 개발 환경과 운영 환경에서 데이터베이스 연결 설정이 다를 수 있는데, 이때 환경에 맞는 설정을 외부 파일에서관리할 수 있다.
    - 중요한 데이터를 설정 파일에 하드코딩하는것보다 외부에 안전하게 관리하는 것이 보안상의 이점이있다.  

     
     

    🖇️ < environments >

    데이터 베이스 환경 설정을 정의하는 부분이다. ( MyBatis에서 데이터베이스 환경 설정을 정의하는 중요한 요소! )
    코드에서는 'dev'라는 환경을 설정하고 JDBC 타입의 트랜잭션 관리자 POOLED 타입의 데이터 소스를 사용한다고 명시하고 있다.

    더보기

    * 트랜잭션 관리자(Transaction Manager)

    트랜잭션 관리자는 데이터베이스 연산을 단일 논리적 단위로 묶어서 일관성을 유지하고 데이터 베이스에서 변경을 안전하게 처리하는 역할을 한다.

     

    MyBatis에서 일반적으로 사용하는 관리자 유형

    •  JDBC : 기본적으로 제공하는 트랜잭션 관리 방식이다.
      JDBC API를 사용하여 트랜잭션을 관리한다. 이 방식은 데이터베이스 벤더의 트랜잭션 관리 기능에 의존한다.
    • MANAGED : 컨테이너에서 제공하는 관리형 트랜잭션을 사용한다.
      예) JAVA EE 환경의 컨테이너가 JTA(Java Transaction API)를 통해 관리형 트랜잭션을 제공할 수 있다.

     

    JDBC 데이터 소스는 각 SSQL 세션마다 새로운 데이터베이스 연결을 만든다..

    즉, 매번 데이터베이스에 접근할 때마다 새로운 연결을 생성하고 SQL 작업이 끝나면 연결을 닫는다..
    장점
    - JDBC 데이터 소스는 특별한 설정 없이도 바로 사용할 수 있다.

    - 세션마다 새로운 연결을 사용하기에 연결이 항상 최신 상태이벼 외부적인 연향을 받지 않는다.

     

    단점
    - 매번 연결을 생성하고 해제하는 과정에서 성능 저하가 발생할 수 있다.

    특히 데이터베이스 연결이 빈번할 경우, 큰 부하가 유발된다.

    - 여러 클라이언트가 동시 접근할 경우, 데이터베이스 연결을 효율적으로 관리하기 어려울 수 있다.

     

    * 데이터 소스

    데이터 소스는 데이터베이스와의 연결을 관리하고 데이터베이스 연산을 수행하기 위한 연결을 제공하는 객체이다.

     

    일반적으로 사용하는 데이터 소스 

    • UNPOOLED
      각 SQL 세션이 별도의 데이터베이스 연결을 가지고 있는 단순한 데이터 소스이다.
      매번 연결을 생성하고 해제한다 > 성능이 저하될 수 있다.
    • POOLED
      데이터베이스 연결을 풀링하여 재사용함으로 성능을 향상시키는 데이터 소스이다
      여러 클라이언트가 동시접근하는 경우 유용하다.
    • JNDI
      Java Naming nad Directory Interface를 사용하여 컨테이너 관리형 데이터 소스를 사용할 ㅜㅅ 있다.

    POOLED 데이터 소스는 데이터베이스 연결을 풀에 미리 생성하고 관리한다.

    SQL 작업이 필요할 때마다 풀에서 연결을 가져와 사용하고 작업이 끝나면 풀에 반환한다.

     

    장점

    - 연결 풀링을 통해 데이터베이스 연결을 재사용한다. 연결 생성 및 해제에 따른 오버헤드를 줄일 수 있다.

    - 연결을 재사용하기에 연결 수 가 과도하게 증가하지 않는다.

    단점

    - 연결 풀을 설정하고 관리하는 것이 필요하다. 적절한 크기와 설정으로 관리하지 않으면 자원 소모가 발생할 수 있다.

    - 풀에 준비된 연결이 크지 않거나 관리가 잘못되면 동시성 문제가 발생한다.

     

     
     

    🖇️ < dataSource >

    데이터베이스 연결을 위한 설정이다. POOLED 타입의 데이터 소스를 사용하며, 각 속성들은 ${ .. } 형태로 외부에서 제공되는 값들을 참조한다. (위쪽 플레이스 홀더 참고)

     

    🖇️ < mappers >

    SQL 매핑을 정의한 XML 파일을 명시한다. 실제 SQL 쿼리와 자바 객체 사이의 매핑을 담당한다.

     

    🖇️ < typeAliases  >

    자바 객체의 별칭을 설정하는 곳이다.
    SQL 매퍼에서 별칭을 사용해서 객체를 참조할 수 있다.
     
     

    💻 MyBatis 프레임워크와 데이터베이스 연결 설정

    MyBatis에서 중요한 객체인 SqlSessionFactory를 생성하는 파일이다.
    이 파일에서는 설정 파일(Configruration.xml)을 기반으로 SqlSessionFactory를 생성하여 데이터 베이스와의 연결을 설정하는 역할을 한다.
    MyBatis를 사용하여 데이터 베이스와의 연동을 어떻게 설정하는지 알 수 있다.
     

     

    🖇️ SqlSessionFactory

    MyBatis 프레임워크에서 중요한 인터페이스이다.
    데이터베이스와 연결을 설정하고 SQL세션을 생성하는 역할을 한다.
     
    https://hi-hahahoho.tistory.com/91
     

    🖇️ Reader

    자바에서 텍스트 기반 데이터를 읽기 위한 추상 클래스이다.
    해당 클래스는 특정 기능을 수행하기 위해 만들어진 간단하고 재사용 가능한 메서드(Utility Method)이다.
    클래스 패스(java에서 클래스 파일을 찾는 경로)나 파일 시스템에서 지정된 리소스를 Reader 형태롤 가져온다.
     

    🖇️ SqlSessionFactoryBuilder

    MyBatis에서 제공하는 클래스이다. MyBatis 설정 파일을 읽어와서 SqlSessionFactory 인스턴스한다.
    DB세션을 생성하고 관리하는 인터페이스이다.
     
    reader로 읽은 설정 파일 정보를 sqlSessionFactoryBuilder에 전달하여 bulid() 메서드를 호출하여 SqlSessionFactory 객체를 생성한다.
     
    해당 객체는 한번만 사용하고 버리는 일회용 객체이다. 단일 역할을하며 재사용되지 않는 객체란 의미.
    즉, 매번 새로운 SqlSessionFactoryBuilder를 생성할 필요없다.
    보통 애플리케이션 전체에서 하나의 SqlSessionFactory를 재사용한다.
     

    더보기

    이름에서 알 수 있듯 해당 클래스는 Builder 패턴을 따르는 클래스이다.

    Builder 패턴은 객체를 생성하는 복잡한 과정을 캡슐화하고, 객체의 생성 과정을 단계적으로나누는 디자인 패턴을 말한다.

    Builder 패턴을 사용하면 객체의 생성 과정을 유연하게 관리하고 설정 옵션을 설정할 수 있다. 

     

    🖇️ static {}

    정적 초기화 블록을 사용했다.
    static 초기화 블록은 클래스가 로드될 때 한번 실행되며 sqlSession 필드를 초기화한다.
     sqlSession 필드와 getSqlSession() 메서드를 사용해서 싱글톤 패턴을 구현했다.
    애플리케이션 전역에서 단 하나의 sqlSessionFactory 인스턴스를 사용할 수 있다.
     
    static 필드와 메서드는 클래스 레벨에서 공유되므로 여러 인스턴스가 같은 데이터를 참조하고 공유할 수있다. 
    즉, 인스턴스 독립성이 생긴다.
     

    👏 정리

    1. myBatis 설정

    : MyBatis 프레임워크에서 사용되는 xml 파일.
     데이터베이스와 연결 정보 설정, SQL 매퍼 파일 위치 설정 ..
     

    2.MyBatis 프레임워크를하여 데이터베이스와 연결을 설정

    MyBatis를 초기화
    설정 파일을 기반으로 SqlSessionFactory를 생성한다. 
     
     


     
     

    😊정리

    SqlSessionFactory는 SqlSessionFactoryBuilder을 통해 생성된다.
    Factorybuilder를 정리하다가 일회용 객체라는 말에 순간적으로 singleton 패턴이 내부적으로 이뤄지나? 하는 착각을 했다.
    다시 정리하면서 아니라는 것을 알았지만 디자인 패턴에 대한 지식이 전무하다는 것을 깨달았다.
    내가 사용하는 클래스에는 많은 디자인패턴이 쓰이지만 하나씩 해석해가며 사용하지 않아서 개념을 잊게 된다.
    다시 공부해보는걸로..!
     
    나중에라도 다시 볼 블로그
    https://barunmo.blogspot.com/2013/06/mybatis.html