MyBatis
。SQL을 통해DB 상호작용시 자동으로객체로매핑하는SQL Mapper역할의프레임워크
▶ 이전 버전은iBatis라고 한다.
。MyBatis를 통해SQL과JAVA 코드와 독립되어 분리되어있으므로,SQL을 따로 관리가능
。CRUD 과정을IoC를 통해개발자가 아닌,MyBatis Framework가 수행
。단일 책임 원칙에 따라서DAO 역할만 수행하며,DB Connection은사용자가 직접 정의해야한다.
。MyBatis는 기본적으로DBMS에 대해Auto Commit이비활성화된 상태.
▶SqlSession객체.commit()을 통해 일일이Commit을 수행
。Mybatis 설정
SQL Mapper
。SQL을 통한데이터 조회시 해당데이터를객체와매핑하는 용도의 도구
MyBatis 설정시 주의사항
Mapper.xml 파일은resources 이하 디렉토리에서 반드시매핑되는Mapper 인터페이스와 동일한디렉토리명.파일명으로 등록해야한다.
ex )src/main/java/mapper/TestMapper.Interface인 경우src/main/resources/mapper/TestMapper.xml로 설정
。MyBatis의설정파일은 반드시<configuration>,<environments>,<environment>,<transactionManager>,<dataSource> 태그를 가져야한다.
。각태그는Java에서Java Bean으로 가질 수 있다.
<configuration>
。Java Bean 생성Configuration configuration = new Configuration(Environment객체);
Configuration객체.getEnvironment()
。MyBatis 전역설정파일의<Environment> 태그를자바 객체로서 가져오는메서드
Configuration객체.setMapUnderscoreToCamelCase(Boolean)
。Java의camelCase를 자동으로DBMS의snake_case로 변환하는메서드
Configuration객체.addMapper("디렉토리" or "디렉토리.인터페이스명")
。참조할Mapper 인터페이스를 지정하는메서드
▶디렉토리내 여러Mapper 인터페이스등록 시인터페이스들을 저장중인디렉토리를 설정
。<mappers> -> <package> 태그역할과 유사
<environment>
。Java Bean 생성Environment environment = new Environment( "환경ID", TransactionFactory객체, DataSource객체 );
Environment객체.getDataSource()
。MyBatis 전역설정파일의<DataSource> 태그를자바 객체로서 가져오는메서드
<dataSource type="POOLED">:
。<property>를 통해DB 접속정보를 정의하는태그
▶MyBatis는사용자가DB Connection을 따로 설정해야하므로,<dataSource>를 통해DB 접속정보정의
。type="UNPOOLED":Connection Pool이 없는 경우 선언
。type="POOLED":MyBatis에 구현된Connection Pool을 사용하도록 선언
▶POOLED설정 시MyBatis는 기본적으로 제공하는PooledDataSource로 제공
。type="설정클래스명": 해당설정 클래스에서 반환하는DataSource객체를Connection Pool로 지정
▶HikariCP를 지원하지 않으므로, 다른 방법으로HikariCP를 사용하도록 직접 설정해야함
。Java Bean 생성private static final String DRIVER = "com.mysql.cj.jdbc.Driver"; private static final String URL = "jdbc:mysql://localhost:3304/mybatis_shop"; private static final String USER = "root"; private static final String PASSWORD = "wjd747"; PooledDataSource pooledDataSource = new PooledDataSource(); pooledDataSource.setDriver(DRIVER); pooledDataSource.setUrl(URL); pooledDataSource.setUsername(USER); pooledDataSource.setPassword(PASSWORD);
<transactionManager>:
。DB에서 발생하는트랜잭션을IoC 역할로서 관리하는 역할을 수행.
▶type="JDBC":JDBC를 통해 발생하는트랜잭션을 관리
。Java Bean생성JdbcTransactionFactory jdbcTransactionFactory = new JdbcTransactionFactory();
<mappers>
。MyBatis 전역설정파일에서 활용할Mapper를 등록하는Mapper Registry역할의태그
▶MyBatis는 기본적으로 어떤Mapper를 사용할 건지 자동으로식별하지 못하므로, 특정Mapper 파일를 사용하도록 등록해야함.
Mapper를 등록하는 방법
<mapper resource="Mapper.xml파일경로"> 태그를 통해Mapper를 직접 등록
。src/main/resources기준절대경로로서 사용할Mapper 파일의경로를 직접 설정<mappers> <mapper resource="mapper/TestMapper.xml"/> </mappers>
<package name="디렉토리 경로"> 태그를 통해인터페이스를 등록
。<package name="인터페이스 디렉토리 경로">설정 시 해당패키지내 모든Mapper 인터페이스를 자동으로 검색 및 등록
。src/main/java기준절대경로로서인터페이스가 위치한패키지 경로를 설정
ex )com.uos.mybatis.s1 = src/main/java/com/uos/mybatis/s1<mappers> <!-- package 태그는 반드시 name 속성을 포함 --> <!-- src/main/java를 기준으로 인터페이스가 위치한 패키지명을 입력--> <package name = "com.uos.mybatis.s1"/> </mappers>
<mapper namespace="그룹명">or<mapper namespace="패키지명.인터페이스명">
。Mapper.xml 파일내에서SQL매핑태그들을 묶는 역할을 수행하는태그
▶ 주로SQL Query와Java Interface를Mapping하는 역할을 수행
。 내부에CRUD와Parameter Binding기능이 포함된태그(select / insert / update / delete)를 구현하여DB Query를 작성
。namespace="패키지명.인터페이스명":src/main/java를 기준으로절대경로로서 연결할Mapper 인터페이스를 지정
▶ 지정 시MyBatis가Mapper 인터페이스를 자동으로스캔하여 식별
<mapper> 내 SQL매핑태그종류
<select>: 조회
。SELECT SQL문을매핑하는태그
<insert>
。INSERT SQL문을매핑하는태그
<update>
。UPDATE SQL문을매핑하는태그
<delete>
。DELETE SQL문을매핑하는태그
SQL매핑태그속성
id="식별자" / id="인터페이스 추상메서드명":
。각SQL Query를 식별하는식별자 속성
▶ 반드시 겹치면 안되고, 유일하게식별가능해야한다.
。SqlSession객체.selectOne()사용 시namespace명.id명을 통해식별됨
。인터페이스 방식사용 시id="인터페이스 추상메서드명"으로 지정
▶ 설정 시인터페이스 추상메서드와SQL매핑태그는 서로 바인딩되어 연동되므로,추상메서드호출 시SQL매핑태그에 정의된SQL문이 실행
resultType="반환타입":
。<select>실행 시반환 Type을 지정하는속성
。자바 클래스로반환 Type지정 시 TypeAliasRegistry를 통해 해당자바 클래스가 저장된패키지 경로로 설정하여SQL매핑태그의Return Type으로서 정의할 수 있도록 설정
SqlSessionFactory
。MyBatis의DB 접속정보를 포함한 전체설정 정보와실행 환경을 내부에 포함하고 있는컨테이너 객체
▶디자인패턴 : 팩토리 패턴으로 구현되어 주로SqlSession 객체를 생성하는 용도로 사용// 전역설정파일.xml 을 통해 생성 시 new SqlSessionFactoryBuilder.build(InputStream객체); // 전역설정을 Java Bean에서 수행하여 Configuration 객체를 정의해서 생성 시 new SqlSessionFactoryBuilder.build(Configuration객체);▶
SqlSessionFactoryBuilder는디자인패턴 : 빌더 패턴을 통해 구현
SqlSessionFactory객체.openSession()
。SqlSession 객체를 생성하는메서드
。openSession(true):Auto Commit이활성화된SqlSession 객체를 생성
SqlSessionFactory객체.getConfiguration()
。MyBatis 전역설정파일의<Configuration> 태그를자바 객체로서 가져오는메서드
SqlSession
。MyBatis에서DAO 역할을 수행하는객체
▶PreparedStatement와 유사
。SqlSessionFactory객체.openSession()에 의해MyBatis 전역설정파일의 설정을 기반으로 생성
▶openSession(true)를 통해 생성된 경우Auto Commit이활성화됨
。 내부에MyBatis 전역설정파일에 포함된DB 접속정보를 기반으로 자동으로DB Connection을 생성 및 포함하므로,try ~ with문을 통해SqlSession 객체를 종료해야함.
。Thread Safe하지 않은 특징이 존재하므로,Thread Pool을 통한병렬 작업은 가급적 지양하는게 좋다.
▶SqlSession은스레드당SqlSession 객체를 단 한개만 생성하여 작업
SqlSession객체.getMapper(Mapper인터페이스.class)
。클래스리터럴을 통해Mapper 인터페이스의클래스 타입을 정의한인터페이스 구현체를 생성
▶구현체에 포함된메타데이터를 이용하여인터페이스의추상 메서드를 사용하도록 설정
。Mapper 인터페이스 구현체의인스턴스 메서드호출 시Mapper.xml파일에서바인딩된SQL태그의SQL문을 자동 실행하도록 설정됨SqlSession sqlSession = build.openSession(); // Mapper Interface 구현체 생성 TestMapper mapper = sqlSession.getMapper(TestMapper.class); // 추상메서드 호출 시 바인딩된 SQL매핑태그를 자동실행 Integer test = mapper.test(); sqlSession.close();
SqlSession객체.commit() / SqlSession객체.rollback()
。Commit / Rollback을 수행
▶MyBatis는Auto Commit이 기본적으로비활성화되어 있으므로 다음메서드를 활용
。SqlSessionFactory객체.openSession(true)를 설정 시Auto Commit을활성화시킬 수 있다.
Mybatis 의존성정의
。build.gradle 설정파일에 정의
▶ Mybatis// Source: https://mvnrepository.com/artifact/org.mybatis/mybatis implementation 'org.mybatis:mybatis:3.5.19'
MyBatis 전역 설정 파일정의
。DB와Mapping되는명세를 정의하는파일
▶MyBatis 관련 객체생성 시 해당파일의 설정을 기반으로 생성
。Mybatis 공식문서 참고
。src - main - resources아래mybatis-config.xml를 생성하여 설정<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <environments default="exp1"> <environment id="exp1"> <!-- Transaction Manager : IoC 역할 수행 --> <transactionManager type="JDBC"/> <!-- dataSource --> <dataSource type="POOLED"> <!-- 접속정보 정의 --> <property name = "driver" value="com.mysql.cj.jdbc.Driver"/> <!-- 자기 닫힘 태그 --> <property name = "url" value="jdbc:mysql://localhost:3304/practice_db"/> <!-- 자기 닫힘 태그 --> <property name = "username" value="kf16"/> <!-- 자기 닫힘 태그 --> <property name = "password" value="wjd747"/> <!-- 자기 닫힘 태그 --> </dataSource> </environment> </environments> <!-- Mapper Repository --> <mappers> <!-- 각 도메인별 TestMapper 데이터를 수동 정의 --> <mapper resource="mapper/TestMapper.xml"/> </mappers> </configuration>▶
MyBatis Mapper 파일정의
。실제 실행할SQL 규칙을 작성
metadata및<mapper>정의<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="test"> <select id="test" resultType="int"> -- SQL 구문 입력 SELECT 1 </select> </mapper>。
<select>식별 시test.test로 식별.
▶sqlSession.selectOne("test.test");
Java 코드작성
。MyBatis 전역설정파일( =mybatis-config.xml)의패키지.파일명를 전달하여InputStream생성 ->SqlSessionFactory 객체생성 ->SqlSession 객체생성public class SessionFactory { public static void main(String[] args) throws IOException { // MyBatis 전역설정 XML파일에 대한 src/main/resources 기준 절대경로의 파일명을 지정 String xmlFilerDir = "mybatis-config.xml"; // 전역설정파일을 기반으로 InputStream으로 변환 InputStream inputStream = Resources.getResourceAsStream(xmlFilerDir); // SqlSessionFactory 객체 생성 SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); // SqlSession 객체 생성 : 내부에 Connection을 포함하므로 반드시 close try( SqlSession sqlSession = sqlSessionFactory.openSession(); ){ // 전역설정파일 내 <dataSource> 태그 정보를 자바객체로 가져옴 DataSource dataSource = sqlSession.getConfiguration() .getEnvironment() .getDataSource(); System.out.println("DataSource Class :" + dataSource.getClass().getName()); // 전역설정파일의 <mappers>로 등록된 Mapper 파일(mapper/TestMapper.xml)에 정의된 SQL태그를 호출 // Mapper파일 내 "namespace명.id명"으로 SQL태그를 식별 및 실행 Integer i = sqlSession.selectOne("test.test"); System.out.println("result : " + i); } catch ( Exception e ) { e.printStackTrace(); } } }。
DataSource Class : org.apache.ibatis.datasource.pooled.PooledDataSource출력
▶전역설정파일의<dataSource type="POOLED">로 설정되어있으므로,MyBatis의Connection Pool(=PooledDataSource)를 사용하여SqlSession 객체를 생성하도록 설정