이것 저것 개발 공부/MyBatis
[MyBatis] MyBatis Java 기반 설정 방법 | XML 없이 MyBatis 설정하기
crushed-taro
2025. 3. 8. 14:30
728x90
반응형
[MyBatis] MyBatis
1. MyBatis 개요1. MyBatis란데이터의 입력, 조회, 수정, 삭제(CRUD)를 보다 편하게 할 수 있도록 xml로 구조화한 Mapper설정 파일을 통해 JDBC를 구현한 영속성 프레임워크이다.기존에 JDBC를 통해 구현했던
crushed-taro.tistory.com
1. Environment class
1. Environment란
- 데이터베이스 접속에 관한 환경 설정 정보를 가진 객체로, MyBatis 환경 설정 객체를 생성하는 데 사용한다.
- MyBatis Framework 라이브러리에서 제공하는 클래스이다.
2. Environment 객체 생성 방법
Environment environment = new Environment(환경 정보 이름, 트랜잭션 매니저 종류, 커넥션풀 사용 여부);
- Environment 클래스는 기본 생성자를 제공하지 않는다.
- 객체 생성 시 전달하는 매개변수는 차례로 다음과 같다.
- 환경 정보 이름 : 생성할 환경 정보의 이름을 설정한다.
- 트랜잭션 매니저 종류는 두 가지가 있고, 안전한 트랜잭션 관리를 위해 JdbcTransactionFactory 사용을 권장한다.
- JdbcTransactionFactory : 코드 작성을 통해 수동으로 커밋을 조작
- ManagedTransactionFactory : JDBC가 자동으로 커밋을 수행
- 커넥션풀 사용 여부에 따라 두 가지 설정을 할 수 있고, 사용하는 경우 Connection 속도 및 메모리 효율이 증대되는 장점이 있다.
- 어떤 설정을 사용하든 생성 시 데이터베이스 연결을 위한 설정 정보(드라이버, 데이터베이스 URL, USER, 비밀번호)를 인자값으로 주어야 한다.
- PooledDataSource : ConnectionPool 사용
- UnpooledDataSource : ConnectionPool 사용하지 않음
PooledDataSource | UnpooledDataSource | |
특징 | 최초 Connection 객체를 생성 시 해당 정보를 pool 영역에 저장해 두고, 이후 Connection 객체를 생성할 때 이를 재사용한다. | Connection 객체를 별도로 저장하지 않고 , 객체 호출 시 매번 생성하여 사용한다. |
장점 | Connection 객체를 생성하여 Database 와 연결을 구축하는데 걸리는 시간이 단축된다. | Connection 연결이 많지 않은 코드를 작성할 때 간단하게 구현할 수 있다. |
단점 | 설정해야 할 정보 자체가 많기 때문에 단순한 로직을 수행하는 경우에는 Connection 객체를 생성하는 비용 자체가 다소 아깝다. | 매번 새로운 Connection 객체를 생성하므로 속도가 상대적으로 느리다. |
3. Environment class 사용 예시
Environment environment = new Environment("dev", new JdbcTransactionFactory(), new PooledDataSource(DRIVER, URL, USER, PASSWORD));
2. Configuration class
1. Configuration이란
- 환경 설정 정보 Environment 객체를 가지고 생성한 MyBatis 설정 객체로, DB 접속 관련 정보, mapper 등록, 별칭 등록 등 myBatis 전역 설정 정보를 담고 있다.
2. Configuration 객체 사용 예시
Configuration configuration = new Configuration(environment);
configuration.addMapper(Mapper.class);
- addMapper() 메서드는 설정 객체에 메퍼를 등록한다.
3. SqlSessionFactory와 SqlSession
1. SqlSessionFactory와 SqlSessionFactoryBuilder
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(configuration);
- SqlSessionFactory
- SqlSession 객체를 생성하기 위한 팩토리 역할을 수행하는 인터페이스이다.
- 애플리케이션이 실행되는 동안 여러 차례 빌드하지 않도록, 싱글톤 패턴 등을 이용하여 어플리케이션 스코프로 사용하는 것이 좋다.
- SqlSessionFactoryBuilder
- SqlSessionFactory 인터페이스 타입의 하위 구현 객체를 생성하기 위한 빌드 역할을 수행한다.
- build() 메소드는 설정 정보를 담고 있는 Configuration 타입의 객체 혹은 외부 설정 파일과 연결된 스트림을 매개변수로 전달하면 SqlSessionFactory 인터페이스 타입의 객체를 반환한다.
- SqlSessionFactoryBuilder 메소드
method 구분 설명 build(InputStream) config.xml 파일만 불러옴 build(InputStream, String) config.xml 파일과 지정한 데이터베이스를 불러옴 build(InputStream, Properties) config.xml파일과 property 로 설정한 내용으로 불러옴(“${key}”) build(InputStream, String, Properties) config.xml 파일과 지정한 데이터베이스, properties 파일 불러옴 build(configuration) configuration 객체에 설정한 내용을 불러옴 - config.xml은 Resource객체의 getResourceAsStream 메소드를 이용해 InputStream으로 가져온다.
2. SqlSession
SqlSession sqlSession = sqlSessionFactory.openSession(false);
- SqlSessionFactory의 openSession() 메소드를 사용하여 SqlSession 인터페이스 타입의 객체를 반환받는다.
- SqlSession은 멀티 스레드 환경에서 안전하게 사용할 수 없으므로(= Thread-safe 하지 않음), 스레드마다 생성하여 공유되지 않도록 해야 한다.
- 따라서 HTTP 요청 라이프사이클과 유사하게, 요청 시 생성하고 요청 처리가 완료되면 close하는 스코프를 권장한다.
- openSession() 메소드
- boolean 타입을 인자로 전달하는데, 이는 Connection 인터페이스 타입 객체로 DML 수행 후 auto commit 여부에 대한 옵션을 의미한다.
- auto commit 옵션은 false로 지정하여 트랜잭션을 직접 관리할 수 있도록 하는 것을 권장한다.
method 구분 설명 openSession() 기본값을 통해 SqlSession 생성 openSession(Boolean) - SqlSession 생성 시 AutoCommit 여부 지정
- 기본값 = trueopenSession(Connection) - 직접 생성한 Connection 객체를 이용해 SqlSession 생성
- 기본값 = XopenSession(ExecutorType) - 쿼리 실행 시 PreparedStatement의 재사용여부 설정
- 기본값 = ExecutorType.SIMPLE - Mybatis SqlSessionFactory를 통해 Session을 생성하는 openSession() 메소드는 여러가지 형식으로 오버로딩 되어있는데, 그중 대표적인 것은 다음과 같다.
- SqlSession은 사용 후 반드시 close()하여 반납해야 한다.
sqlSession.close();
- mapper.xml에서 선언한 쿼리 구문을 SqlSession에서 실행하는 메소드는 총 6가지로 아래와 같다.
method명 | 설명 |
Object selectOne(String mapper, Object param) | 하나의 객체만을 받을 때 사용 |
List<E> selectList(String mapper, Object param) | 결과에 대한 값을 List로 받을 때 사용 |
Map<K,V> selectMap(String mapper, Object param, String mapKey) | 결과에 대한 값을 Map으로 받을 때 사용 (마지막 인자로 key로 사용될 컬럼 명시) |
int insert(String mapper, Object param) | Database에 데이터를 입력할 때 사용 |
int update(String mapper, Object param) | Database의 데이터를 수정할 때 사용 |
int delete(String mapper, Object param) | Database의 데이터를 삭제할 때 사용 |
3. MyBatis 인스턴스들의 Scope와 Life-Cycle
- SqlSessionFactoryBuilder : 로컬 스코프 → 메서드 내부, 또는 초기화 블럭 내부
- 일반적으로 한 번 SqlSessionFactory를 빌드하고 나면 더 이상 필요하지 않다. (일회용)
- 따라서 짧은 라이프 사이클을 가지게 되며 더 이상 필요하지 않게 되면 즉시 가비지 컬렉터의 대상이 될 수 있다.
- 일반적으로 데이터베이스 작업(CRUD 외 DDL 등)을 수행하는 동안에만 유효하기 때문에 짧은 라이프 사이클을 가지게 된다.
- SqlSessionFactory : 애플리케이션 스코프 → 싱글턴 패턴 사용
- 애플리케이션 내에서 단 하나만 생성되도록 관리해야 한다.
- 애플리케이션이 실행되는 동안 SqlSessionFactory가 여러 번 빌드되지 않도록 하는 것이 가장 좋은 형태다.
- 애플리케이션이 실행되는 동안 여러 스레드(=SqlSession)에서 공유되기 때문에 긴 라이프 사이클을 가지게 된다.
- SqlSession : 메서드 스코프 or 트랜잭션 스코프 → 메서드 내부, 또는 트랜잭션 범위 내부
- 추후 웹 요소가 결합되면 HTTP 요청과 밀접한 생명 주기를 가져간다. 즉, HTTP 요청이 발생했을 때 객체가 생성되고, 요청에 대한 HTTP 응답이 전송되면 객체를 폐기하면 되기 때문에 HTTP 요청과 유사한 스코프에 두는 것이 가장 올바른 방법이다.
- 데이터베이스 작업이 끝난 후에는 반드시 close() 메서드를 호출하여 리소스를 반환해야 하며, 그렇지 않으면 연결 누수(Connection Leak)가 발생하게 되고 이는 메모리 누수(Memory Leak)로 이어질 수 있다.
728x90
반응형