JAVA/ORM

SqlSessionFactory 클래스 정리

읽히는 블로그 2024. 7. 29. 19:22

▤ 목차

     

     

     

    MyBatis를 배우는데 자연스럽게 사용하지만 궁금한 인터페이스가 있었다.

    SqlSessionFactory는 MyBatis 프레임워크에서 중요한 인터페이스 중 하나이다.

    이 인터페이스는 데이터베이스와의 연결을 설정하고 SQL 세션을 생성하는 역할을 한다.

    이름에서 알 수 있는 점은, Factory 패턴이 사용되었다는 점이다.

     

    ✔ SqlSessionFactory 인터페이스 정의

    SqlSessionFactory는 MyBatis에서 DB와의 연결을 설정하고 SQL 세션을 생성하는 인터페이스이다.

    MyBatis는 데이터베이스 접근 계층을 제공한다.

    개발자는 SQL 매퍼 파일을 통해 SQL 쿼리와 자바 객체 간의 매핑을 할 수 있다.

     

    ⌨ 인터페이스  정의

    해당 API문서

     

    public interface SqlSessionFactory {
        
        SqlSession openSession();
        
        SqlSession openSession(boolean autoCommit);
        
        SqlSession openSession(Connection connection);
        
        SqlSession openSession(TransactionIsolationLevel level);
        
        SqlSession openSession(ExecutorType execType);
        
        SqlSession openSession(ExecutorType execType, boolean autoCommit);
        
        SqlSession openSession(ExecutorType execType, TransactionIsolationLevel level);
        
        SqlSession openSession(ExecutorType execType, Connection connection);
        
        Configuration getConfiguration();
        
    }

     

     

    이렇게 Interface로 정의되어 있다.

    대부분의 인터페이스는 openSession 메서드를 오버로딩해 놓은 것을 알 수 있다.

    마지막에 getConfiguration()메서드가 있는데 이를 통해 해당 SqlSessionFatory의 설정 정보를 반환한다.

     

     

     


     

     

     

    ✔ SqlSessionFactory 주요 메서드

    🔦 openSession()

    SqlSession openSession();

     

    기본적으로 DB와 새로운 SQL 세션을 열때 사용한다.

    이 메서드는 기본 설정으로 세션을 연다.

     

    🔦 openSession(boolean autoCommit)

    SqlSession openSession(boolean autoCommit);

     

    세션을 열때 자동 커밋 여부를 지정할 수 있다.

    autoCommit이 true인 경우, 세션이 열리면 자동으로 커밋한다.

    false인 경우, 명시적으로 커밋을 호출해야한다.

    즉, 데이터 변경 사항을 반영을 자동으로할지, 수동으로 할지 정하는 것이다.

     

    🔦 openSession(Connection connection)

    SqlSession openSession(Connection connection);

     

    JDBC 연결을 사용해 세션을 사용한다.

    MyBatis는 이미 존재하는 JDBC 연결을 이용해 세션을 시작할 수 있다.

     

     

    🔦 openSession(TransactionIsolationLevel level)

    SqlSession openSession(TransactionIsolationLevel level);

     

    지정된 트랜잭션 레벨(DB 트랜잭션의 격리 수준)을 설정할 수 있다.

    DB 트랜잭션은 동시에 여러 사용자가 접근하는 경우, 발생할 수 있는 문제를 관리하기 위해 격리 수준을 설정한다.

     

     

    🔦 openSession(ExecutorType execType)

    SqlSession openSession(ExecutorType execType);

     

    지정된 execuType으로 세션을 연다.

    ExecuType은 SQL 실행 방식을 제어하는 역할을 한다.

    기본값은  ExecutorType.SIMPLE 이라고 한다.

     

    🔦  getConfiguration()

    Configuration getConfiguration();

     

    해당 SqlSessionFactory 인스턴스의 설정 정보를 반환한다.

    설정 정보에는  데이터베이스 연결 정보, sql 매퍼 위치, 타입 별칭(alias) 등 정보가 포함되어 있다.

     

     

     

     

     


     

     

    ✔ SqlSessionFactory의 역할

    📌SQL 세션 생성

    위의 코드에서 봤다시피 데이터베이스와 연결을 설정하고 SQL 세션을 생성한다.

    ( DB와 실제 연결을 설정하고 해당 연결을 통해 SQL 쿼리를 실행할 준비를 하는 과정 을 )

    📌 환경 설정 관리

    데이터 베이스 연결 정보, 트랜잭션 관리 방법, SQL 매퍼 파일 위치 등의 환경 설정을 관리한다.

     

    📌스레드 세이프

    SqlSessionFactory 는 여러 스레드에서 안전하게 공유할 수있도록 설계해야한다.

    보통 전체에서 하나의 인스턴스를 사용한다.

    즉, 싱글톤 패턴(어떤 클래스의 인스턴스가 단 하나만 생성되고 인스턴스에 대한 전역적 접근(static)을 제공)을 의미한다.

     

     

    📌 트랜잭션 관리

    SqlSessionFactory 를 통해 생성된 객체는 데이터베이스 트랜잭션을 관리한다.

    필요에 따라 커밋(commit) 또는 롤백(rollback)할 수 있다.

    // SQL 세션 생성
    SqlSession sqlSession = sqlSessionFactory.openSession();
    
    try {
        // SQL 세션을 사용하여 데이터베이스 조회 등의 작업을 수행
        List<User> userList = sqlSession.selectList("pack.mapper.UserMapper.getAllUsers");
        
        // 작업 완료 후 세션을 커밋
        sqlSession.commit();
    } finally {
        sqlSession.close(); // 세션 닫기
    }

    이 경우, 관리자가 직접 commit을 하기에 auto-commit은 false일 것이다.

     

     

     

     


     

     

     

    SQL 세션 == HTTP 세션 ?  

    SQL 세션을 연다는 의미

    DB와 실제 연결을 설정하고 해당 연결을 통해 SQL 쿼리를 실행할 준비를 하는 과정을 말한다.

    웹에서 HTTP 세션(쿠키에 넣는)과는 다른 의미이다.

     

    ⌨ SQL 세션의 의미

    1. 데이터베이스 연결 설정
      세션을 열때, 먼저 데이터베이스 연결을 설정한다.
      JDBC 드라이버를 로드하고 데이터베이스 서버에 접속하기 위한 연결 정보를 설정한다.

    2. SQL 쿼리 실행
      SQL 세션을 통해 DB의 SQL쿼리를 실행할 수 있다.
      MyBatis에서는 sql 쿼리를 xml 파일이나 어노테이션을 정의하고 sqlSession을 통해 쿼리를 호출하고 실행한다.

    3. 자원 관리
      SQL 세션을 사용하고 난 후 반드시 세션을 닫아야한다.
      이 과정에서 사용된 데이터베이스 연결과 관련 자원들을 해제하고, 메모리 리소스를 정리한다.
      세션을 닫지 않으면 데이터베이스 연결이 계속 유지된다.
      유지가 계속되면 성능 저하와 자원 누수가 된다.

    4. 트랜잭션 관리
      SQL 세션은 트랜잭션을 관리한다.
      트랜잭션은 데이터베이스에서 하나의 작업 단위를 의미하며 성공적으로 완료되거나 실패할 수 있다.
      SQL 세션을 열면 트랜잭션의 시작을 알린다.
      이에 (설정에 따라 다르겠지만) 커밋과 롤백을 수행할 수 있다.

     

     

    💻 HTTP 세션과 차이점

     

      HTTP 세션 SQL 세션
    목적 클라이언트와 서버 간의 상태 유지를 위해 사용된다.
    주로 사용자 인증정보나 장바구니 등.. 데이터를 저장하고 관리한다.
    DB와 연결과 SQL 작업을 관리하는데 사용된다.
    유지 시간 클라이언트가 해당 웹 애플리케이션에 접속한 후 일정 시간동안 유지된다. SQL 작업을 수행하는 동안만 유지되며 작업이 완료되면 세션을 닫아야한다.
    범위 웹 애플리케이션 내에서 유효하다. 데이터베이스 서버와의 연결을 관리하는 범위이다.

     

     

    👏 중요

    SQL 세션을 연다는 의미는 DB와 연결을 설정하는 것이다.

    SQL 작업을 수행할 수 있는 상태를 만드는 과정을 말한다.

    JDBC 드라이버를 로드하고 데이터베이스 서버에 접속하여 트랜잭션을 관리하고 SQL 쿼리를 실행하고 결과를 받아온다.

    DB의 효율적인 상호작용을 위한 필수적인 과정이다.

     

     

     

     


     

     

    😊정리를 하다가..

    정리를 하다가, 아래와 같은 문장을 보면서 synchroized 키워드를 사용하는 싱글톤과의 차이가 궁금해졌다.

    SqlSessionFactory 는 여러 스레드에서 안전하게 공유할 수있도록 설계해야한다.

    보통 전체에서 하나의 인스턴스를 사용한다.

    싱글톤 패턴 적용(왼쪽 1번/ 오른쪽 2번)

     

    여러 검색과 비교 결결과적으로 try{..}를 사용한(정적 초기화 블록) 코드가 좋은 코드라는 결론이 났다.

      1번(정적 초기화 블록 사용) 2번 (synchronized 사용)
    성능 vs 초기화 지연 클래스 로드 시 한번만 초기화 된다. 처음 호출 될때마다 초기화된다.
    지연 초기화를 제공한다.
    동기화 필요성 정적 초기화 블록을 사용하여 동기화 문제를 방지한다. synchronized 키워드를 사용하여 동시 접근에 대한 문제를 해결했다.
    멀티스레드 환경에서 안전한 접근을 보장해야하는 경우 동기화 처리를 추가할 수 있다.
    예외처리와 리소스 관리 리소스 해제와 예외처리가 필요한 경우, 명시적으로 처리하는 것이 바람직하다. 내부적으로 콜백함수를 사용했기에 명시적으로 해제하는 부분이 없다.

     

     

     

     

     


     

    코드는 다양하게 구현할 수 있어서 비교하는 재미도 있지만 어떤게 더 좋은 코드인지 찾아보는 과정에서 많은 시간이 뺏긴다. 계속하다보면 개념이 체화되어 시간이 줄어들겠지..라는 생각이다.

    언젠가는 뭐가 더 좋은지 생각하면 이유가 딱딱 정리되겠지?

    아직 잘 몰라서, 이런 것들을 찾아보고나면 너무 작은 부분에 시간을 쏟은게 아닌가,하는 불안감?이 생긴다.

    아무튼 정리끝!

     

    디자인 패턴에 대한 정리가 필요하단 생각을 한다.