반응형
01. mybatis에서 경로설정 시 유의
- 자바클래스가 읽어들이는 파일은 일반적으로 src/main/java에 있어야하므로, src/main/java에 mybatis 환경설정 파일을 만드는 것임 ex) mybatis-config.xml
- webapp에 있는 파일은 자바클래스가 아닌 WAS가 읽어들이는 파일임 그래서 웹자원이라 부름 - 웹컨텍스트 루트
02. Logging설정법과 로그팩토리
1) Logging (로깅)
- 로깅이란? 기록하는 것
2) Logging (로깅)이 필요한 이유
- 프로그램의 흐름이 프레임워크에 의해 동작됨
- 즉, 우리가 작성한 코드는 실제로 프레임워크가 실행해줌
- 하지만 작성한 명령들이 제대로 실행되는지 안되는지 기록을 해야함
- 그래서 로깅작업이 필요함
- 하지만, 기록을 받아 기록해주는 구현체가 없으면 눈에 보이지 않음ㅠㅠ
- 내부적으로 어떻게 매핑되서 실행되고 어떤 결과를 주는지 알 수 없으므로, JSP에서는 SQLException 발생되지만, 마이바티스는 SQLException 발생하지 않음
- ibatisException만 발생될 뿐, 문법적으로 어디가 잘못되었는지 알려주지 않음
3) 로그팩토리
- 마이바티스는 내부 로그 팩토리를 사용하여 로깅 정보(기록정보)를 제공함
- 내부 로그 팩토리는 명령이나 예외가 발생할 때마다 로깅정보(기록물)을 제공해줌
- 내부 로그 팩토리는 로깅 정보를 다른 로그 구현체 중 하나에 전달함
4) 로그 구현체
- 사용자에게 실제 출력해서 알려줌!!
- ex) 메일출력, 콘솔출력, 파일에저장, 프린트로 출력, 디버그는 프로그램에 메일로 보내줌..
- 방법은 매우 다양
- 개발자가 프로그램을 관리할 때는 실제 콘솔을 보지 않기 때문에 에러로그 파일을 보며 어떤 문제가 잘못되었는지 판단함
03. 로그구현체의 종류 및 설정법
1) 로그구현체 종류
- 마이바티스는 내부 로그 팩토리를 사용하여 로깅 정보를 제공함
- 내부 로그 팩토리는 로깅 정보를 다른 로그 구현체 중 하나에 전달
- 해당 로그구현체는 위에서 부터 순서대로 없으면 그 다음 없으면 그 다음에게 전달함
- 로깅정보를 로그구현체가 전달받으므로 로그구현체가 필요하며, 로그구현체는 WAS에게 제공받아 사용함
- 하지만 아파치톰캣은 자체적으로 로그구현체가 없으므로 프로젝트에 빌드 처리 필요함!
2) 로그구현체 설정
💜1. 로그구현체를 구성하기 위한 라이브러리 빌드 처리
- 라이브러리의 의존관계에 의해 여러개의 라이브러리가 필요할 수 있으므로 모두 다 빌드처리 필요!!
- 다운받았던 mybatis zip파일의 lib폴더 들어가면 필요한 것들 있으니 모두 프로젝트에 빌드처리하면 WAS의 라이브러리로 사용 가능해짐!!!!!
💜2. 어떻게 기록할 것인가?를 설정
- 로그 구현체를 사용하기 위한 환경설정 ( Logging Configuration )
🖤방법1 : SLF4J
- mybatis 웹프로젝트에서는 사용 안할 것임
- 의존관계에 의해 여러개의 라이브러리 빌드 처리해야하므로 사용안할 것임
🖤방법2 : Log4j2
- 원래 이걸로 이용하려 했으나 다운받아야 하는 라이브러리가 많아 다른 것 이용
🖤방법3 : Log4j - 이용할 것임
🖤방법4 : JDK logging
04. Log4j.xml ( Log4j2.xml )
Log4j2.xml
- 원래 이것을 이용하려고 했으나,, 의존관계에 의해 여러개의 라이브러리 빌드 처리해야하므로 사용안할 것임
- 파일의 위치 및 형식
<?xml version="1.0" encoding="UTF-8"?>
<Configuration xmlns="<http://logging.apache.org/log4j/2.0/config>">
<!-- Appenders태그 : 기록하는 장치-->
<!--어떤 클래스에 의해 기록할 것인가?를 설정 -->
<!-- 파일에 기록, 메일에 저장.. 등등 -->
<Appenders>
<!-- Console태그 : 콘솔에 기록 -->
<!-- name속성: 식별자 -->
<Console name="stdout" target="SYSTEM_OUT">
<!-- pattern속성 : %5level[로그레벨] [%t][스레그] %msg%n[로그메세지]-->
<PatternLayout pattern="%5level [%t] - %msg%n"/>
</Console>
</Appenders>
<!-- 6레벨: 5레벨:error 4레벨:warning 3레벨:info 2레벨:debug 1레벨:tress -->
<!-- 6가지 기록에 대한 레벨 작성되어있음 -->
<!-- 로깅이 언제 발생되엇고, 어떤 레벨을 주었는지 info레벨 이상만 기록 -->
<!-- 딱 에러만 보여줌 : error레벨 이상만 기록해주세요! -->
<!--<Root level="error" >-->
<!-- warning,debug,info,error 레벨..-->
<!-- info레벨 이상만 기록해주세요! -->
<Root level="info" >
<AppenderRef ref="stdout"/>
</Root>
</Configuration>
Log4j.xml - 이용
- Log4j2와 동일하게 구현된 Log4j임
- 콘솔에 기록할 것
- debug이상의 레벨만 로깅됨
- 기록 패턴의 형식은 "%-5p - %m%n"
- 파일의 위치 및 형식
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration SYSTEM "<http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/xml/doc-files/log4j.dtd>">
<log4j:configuration xmlns:log4j="<http://jakarta.apache.org/log4j/>">
<appender name="console" class="org.apache.log4j.ConsoleAppender">
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%-5p - %m%n"/>
</layout>
</appender>
<root>
<level value="DEBUG"/>
<appender-ref ref="console"/>
</root>
</log4j:configuration>
05. mybatis 환경설정 파일
1) mybatis 환경설정 파일명
- 파일명.xml : 아무렇게나 작명 가능
2) mybatis 환경설정 파일을 만드는 이유
- 마이바티스 프로그램의 대부분은 SqlSession클래스가 처리해줌
- SqlSession클래스는 SqlSessionFactory로 만들 수 있으며,
- SqlSessionFactory는 SqlSessionFactoryBuilder로 만들 수 있음
- SqlSessionFactory 객체를 생성하기 위해서는 mybatis 환경설정 파일이 필요한 정보를 제공하기 때문
- 물론 XML을 사용하지 않고 SqlSessionFactory를 빌드할 수도 있음 (즉, xml을 이용하지 않고 자바만을 이용해 만들 수 있음)
- 하지만 비권장 왜?? 유지보수 어려움
- 내용이 바뀔 때마다 자바를 바꿔서 다시 배포해야하기 때문
- 만약 xml로 만들게 되면 재배포가 필요없음
- 따라서 xml(mybatis 환경설정 파일)을 만들어 그 파일을 읽어들여 하는 것을 더 권장
- 실제 mybatis 환경설정파일은 <mappers> 엘리먼트 & <typeAliases>엘리먼트를 지속적으로 추가하기 때문에 매우 자주 변경함
- 자주 변경하는 줄 알았으나 <pakage> 엘리먼트 덕분에 같은 패키지 내 모든 클래스는 패키지를 제외한 클래스 이름을 별칭으로 자동 등록해주고, 같은 패키지 내 모든 인터페이스 기반의 매퍼 파일을 자동으로 매퍼로 등록해줌
3) mybatis 환경설정 파일 작성하기
🖤mybatis-config.xml
- SqlSessionFactory 객체를 생성하기 위해 필요한 정보를 제공하는 환경설정 파일
- 파일의 위치
- 사용가능한 엘리먼트: [mybatis-3-config.dtd] 파일에서 제공해주는 엘리먼트만 사용 가능
- 반드시 엘리먼트 순서대로 작성, doc문서의 매퍼설정 부분 참고
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "<https://mybatis.org/dtd/mybatis-3-config.dtd>">
<!-- DOCTYPE 에서 제공해주는 루트 엘리먼트 : configuration -->
<configuration>
<!-- 🖤properties 엘리먼트 -->
<!-- properties : 1개 이상의 property 엘리먼트를 등록하기 위한 상위 엘리먼트 -->
<!-- resource 속성 : Properties 파일의 경로를 속성값으로 설정 -->
<!-- => property 엘리먼트 대신 [💖Properties 파일]에서 제공되는 값을 mybatis 환경설정 파일에서 사용 가능 -->
<properties resource="dbms.properties">
<!-- property : mybatis 환경설정 파일에 필요한 값을 제공하는 엘리먼트 -->
<!-- => 다른 엘리먼트에서 ${이름} 형식으로 표현하여 property 엘리먼트의 값을 제공받아 사용 -->
<!-- => 다수의 엘리먼트에서 공통적으로 사용되는 값을 제공하기 위해 설정 - 유지보수의 효율성 증가 -->
<!-- name 속성 : property 엘리먼트를 구분하기 위한 식별자를 속성값으로 설정 -->
<!-- value 속성 : property 엘리먼트를 제공하기 위한 값을 속성값으로 설정 -->
<property name="oracleDriver" value="oracle.jdbc.driver.OracleDriver"/>
</properties>
<!-- 🖤settings 엘리먼트 -->
<!-- settings : 1개 이상의 setting 엘리먼트를 등록하기 위한 상위 엘리먼트 -->
<settings>
<!-- setting : mybatis 프레임워크가 실행될 때 필요한 값을 제공하기 위한 엘리먼트 -->
<!-- => setting 엘리먼트를 설정하지 않아도 실행에 필요한 값은 기본값을 제공받아 사용 -->
<!-- => 기본값이 아닌 값을 사용할 경우에만 setting 엘리먼트를 설정하여 실행에 필요한 값을 제공받아 사용 가능 -->
<!-- name 속성: doc문서 참고 -->
<!-- mybatis 자체에서 검색행의 스네이크표기법을 자동으로 카멜표기법으로 변경해줌 -->
<setting name="mapUnderscoreToCamelCase" value="true"/>
<setting name="jdbcTypeForNull" value="NULL"/>
<setting name="callSettersOnNulls" value="true"/>
</settings>
<!-- 🖤typeAliases 엘리먼트 -->
<!-- typeAliases : 1개 이상의 typeAlias 엘리먼트를 등록하기 위한 상위 엘리먼트 -->
<!-- => mybatis 프레임워크는 내부적으로 설정된 Java 자료형에 대한 별칭 제공 : doc문서 참고 -->
<!-- => 많이사용하는 별칭 : string, _int, int, map -->
<typeAliases>
<!-- typeAlias : [XML 기반의 매퍼 파일]에서 Java 자료형을 간단하게 표현하기 위한 별칭(AliasName)을 설정하는 엘리먼트 -->
<!-- => mybatis 프레임워크는 내부적으로 설정된 Java 자료형에 대한 별칭 제공 -->
<!-- type속성 : Java 자료형을 속성값으로 설정 -->
<!-- alias속성 : Java 자료형 대신 사용할 별칭을 속성값으로 설정 -->
<!-- <typeAlias type="xyz.itwill.dto.Student" alias="Student"/> -->
<!-- <typeAlias type="xyz.itwill.dto.MyMember" alias="MyMember"/> -->
<!-- package: 특정 패키지에 작성된 모든 클래스의 별칭을 자동으로 등록하는 엘리먼트 -->
<!-- => 패키지에 작성된 모든 클래스는 패키지를 제외한 [클래스 이름]을 [별칭]으로 자동 등록 -->
<package name="xyz.itwill.dto"/>
</typeAliases>
<!-- 🖤environments 엘리먼트 - 필수 -->
<!-- environments : 1개 이상의 environment 엘리먼트를 등록하기 위한 상위 엘리먼트 (필수) -->
<!-- default 속성: environment엘리먼트의 식별자(id 속성값)를 속성값으로 설정 -->
<!-- => mybatis 프레임워크가 기본적으로 사용하기 위한 DBMS 서버를 표현하기 위한 속성 -->
<environments default="development"> <!-- development서버가 기본값이에요! -->
<!-- environment : DBMS 서버 접속에 필요한 정보를 설정하기 위한 엘리먼트 -->
<!-- id 속성: environment 엘리먼트를 구분하기 위한 식별자를 속성값으로 설정 - 중복불가능!! -->
<!-- environment를 여러개 만든 이유? 서버 여러개 만들어서 test하려고 -->
<environment id="development">
<!-- transactionManager : 트랜잭션 관리자(커밋 또는 롤백 처리)를 설정하기 위한 엘리먼트 -->
<!-- mybatis는 autocommit기능 기본적으로 비활성화 되어있음 -->
<!-- 트랜잭션의 역할 3가지: 잘못된 명령에 대한 취소(commit적용 및 취소) , 일관성있는 데이타를 제공 , 데이타 락기능(동일데이타 변경 금지) -->
<!-- type속성 : [JDBC] 또는 [MANAGED] 둘 중 하나를 속성값으로 설정 -->
<!-- =>[JDBC] : JDBC기능(Connection 객체의 메소드 호출)을 사용하여 직접 트랜잭션 관리, JDBC 커밋과 롤백을 처리하기 위해 사용, 트랜잭션의 스코프를 관리하기 위해 dataSource로 부터 커넥션 가져옴 -->
<!-- => [MANAGED]: 트랜잭션을 관리하는 프로그램을 사용하여 트랜잭션 관리, 트랜잭션을 관리하는 프로그램은 나중에 SPRING할 때 SPRING이 제공해줌 -->
<transactionManager type="JDBC"/>
<!-- dataSource : Connection 객체 생성에 필요한 정보를 설정하기 위한 엘리먼트 -->
<!-- type 속성 : [UNPOOLED] [POOLED] [JNDI] 중 하나를 속성값으로 설정 -->
<!-- => type속성값에 따라 하위 엘리먼트 설정을 다르게 설정 -->
<!-- => [UNPOOLED] : Connection 객체를 미리 생성하지 않고 실행시 생성하여 제공 -->
<!-- => [POOLED] : 다수의 Connection 객체를 미리 생성하여 실행시 제공 - DBCP(DataBaseConnectionPool) : 가장 많이 사용 -->
<!-- => 마이바티스가 내부적으로 컨넥션풀 역할도 해줌 -->
<!-- => [JNDI] : WAS에 등록된 자원(일반적으로 WAS까지 등록시킬 필요는 없음!)을 이용하여 실행시 Connection 객체를 제공 -->
<dataSource type="POOLED">
<!-- property : Connection 객체를 생성하기 위한 값을 설정하는 엘리먼트 -->
<!-- name 속성 : Connection 객체 생성에 필요한 값이 저장될 이름을 속성값으로 설정 -->
<!-- value 속성 : Connection 객체 생성에 필요한 값을 속성값으로 설정 -->
<!-- => driver, url, username, password 4개는 반드시 있어야 Connection 객체 생성 가능 -->
<!-- <property name="driver" value="oracle.jdbc.driver.OracleDriver"/> -->
<property name="driver" value="${oracleDriver}"/>
<!-- <property name="url" value="jdbc:oracle:thin:@localhost:1521:xe"/> -->
<property name="url" value="${local}"/>
<property name="username" value="scott"/>
<property name="password" value="tiger"/>
</dataSource>
</environment>
<!-- => 실제 - local서버(내 서버), test서버(팀만사용하는 서버), real서버(실제배포된 웹프로그램과 연동되는 서버)로 나눠 사용함 -->
<!-- <environment id="local"></environment> --> <!-- ex) local서버 : 내가만든 것 실행할 때-->
<!-- <environment id="test"></environment> --> <!-- ex) test서버 : 단위 프로그램만들 때 -->
<!-- <environment id="real"></environment> --> <!-- ex) real서버 : 통합테스트할 때 -->
</environments>
<!-- 🖤mappers 엘리먼트 - 필수 -->
<!-- => [XML 기반의 매퍼 파일] & [Interface 기반의 매퍼 파일] -->
<!-- mappers : 1개 이상의 mapper 엘리먼트를 등록하기 위한 상위 엘리먼트 (필수) -->
<mappers>
<!-- mapper : 매퍼(Mapper)를 설정하기 위한 엘리먼트 -->
<!-- 매퍼(Mapper) : [SQL 명령에 필요한 값을 전달]받아 [SQL 명령을 등록]하고
[실행결과를 Java 객체(객체 or 원시형)로 매핑]하기 위한 정보를 제공 -->
<!-- mybatis 프레임워크에는 [XML 기반의 매퍼 파일]과 [Interface 기반의 매퍼 파일]을 이용한 매퍼 설정 가능 -->
<!-- =>ibatis 프레임워크에는 XML 기반의 매퍼 파일로만 매퍼 설정 가능 -->
<!-- => 해당 경로에 파일이 없다면 mybatis 동작 아예 실행 안됨 -->
<!-- resource 속성: XML 기반의 매퍼 파일 경로를 속성값으로 설정 -->
<!-- => XML 기반의 매퍼 파일의 경로는 파일 시스템 경로를 기반으로 작성 - xml은 자바가 아니기 때문에 [.]이 아닌 [/]이용해 작성, WAS가 아닌 자바클래스가 읽어들여야하므로 파일의 저장 위치는 classpath 안 -->
<!-- => XML 기반의 매퍼 파일의 장점 : 수동 매핑 설정과 "동적 SQL" 설정에 대한 기능 구현이 편리 -->
<!-- => XML 기반의 매퍼 파일의 단점 : SqlSession 객체로 SQL 명령을 제공받아 사용하기 불편 : DAO 만들기 불편 -->
<mapper resource="xyz/itwill/mapper/StudentMapper.xml"/>
<mapper resource="xyz/itwill/mapper/MyMemberXMLMapper.xml"/>
<!-- class속성 : interface 기반의 매퍼 파일의 경로를 속성값으로 설정 -->
<!-- =>interface 기반의 매퍼 파일의 경로는 Java 자료형(인터페이스)을 기반으로 작성 -->
<!-- => interface 기반의 매퍼 파일의 장점 : SqlSession 객체로 SQL 명령을 제공받아 사용하기 편리 : DAO 만들기 쉬움 -->
<!-- => interface 기반의 매퍼 파일의 단점 : 수동 매핑 설정과 동적 SQL 설정에 대한 기능 구현이 불편 -->
<!-- ===> mapper패키지 안에 등록된 인터페이스는
매퍼로 자동 등록되므로 인터페이스 기반의 매퍼 파일을 설정할 필요 없음! -->
<!-- <mapper class="xyz.itwill.mapper.MyMemberInterfaceMapper"/> -->
<!-- 🔥[XML 기반의 매퍼파일]과 [인터페이스 기반의 매퍼파일]을 [하나의 매퍼로 동작]되도록 설정 -->
<!-- => 🔥매퍼 바인딩(Mapper Binding) : SQL 명령은 XML 기반의 매퍼 파일에 등록하고 DAO
클래스의 메소드는 Interface 기반의 매퍼 파일의 추상메소드를 호출하여 작성 -->
<!-- mapper 엘리먼트는 XML 기반의 매퍼 파일만 등록하여 사용 -->
<!-- ===> mapper패키지 안에 등록된 인터페이스는
매퍼로 자동 등록되므로 매퍼 바인딩이 된 인터페이스 기반의 매퍼 파일을 설정할 필요 없음! -->
<!-- <mapper resource="xyz/itwill/mapper/MyMemberMapper.xml"/> -->
<!-- package : 특정 패키지에 작성된 "모든 Interface 기반의 매퍼 파일"을 자동으로
매퍼로 등록하기 위한 엘리먼트 -->
<!-- name속성 : Interface 기반의 매퍼 파일이 작성된 패키지를 속성값으로 설정 -->
<package name="xyz.itwill.mapper"/>
</mappers>
</configuration>
🖤dbms.properties 파일- 값을 제공할 목적의 파일
#name = value
local = jdbc:oracle:thin:@localhost:1521:xe
06. AbstractSession클래스 - 매퍼를 사용하는 모든 DAO 클래스가 상속받는 부모클래스
💖AbstractSession클래스
package xyz.itwill.dao;
import java.io.IOException;
import java.io.InputStream;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
//SQLSessionFactory 객체를 생성하여 반환하는 기능을 제공하는 클래스
// => 매퍼를 사용하는 모든 DAO 클래스가 상속받기 위한 부모클래스
// => 상속을 목적으로 작성된 클래스이므로 추상 클래스로 선언하는 것을 권장 (생성자 만들 필요 없음)
//단 하나의 SqlSessionFactory만 계속 제공해줄 것임
//=> 일종의 싱글톤 클래스이지만, 은닉화된 생성자는 없음
//클래스가 메모리에 로드되면 static 영역이 먼저 실행되어, SqlSessionFactory가 미리 딱 하나 만들어질 것이며,
//getSqlSessionFactory() 메소드를 호출할 경우 객체 사용 가능
public abstract class AbstractSession {
private static SqlSessionFactory SqlSessionFactory;
static {
String resource = "mybatis-config.xml";
InputStream inputStream = null;
try {
inputStream = Resources.getResourceAsStream(resource);
} catch (IOException e) {
throw new IllegalArgumentException();
}
SqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
}
//상속받은 클래스만 접근가능하도록 접근지정자를 protected로 설정
protected SqlSessionFactory getSqlSessionFactory() {
return SqlSessionFactory;
}
}
반응형
'framework > mybatis' 카테고리의 다른 글
[mybatis] 6. XML + 인터페이스 기반의 매퍼파일 (MyMember 출력 프로그램) (1) | 2024.07.21 |
---|---|
[mybatis] 5. 인터페이스 기반의 매퍼파일 (MyMember 출력 프로그램) (1) | 2024.07.20 |
[mybatis] 4. XML기반의 매퍼파일 (MyMember 출력 프로그램) (0) | 2024.07.20 |
[mybatis] 3. XML기반의 매퍼파일 (Student 출력 프로그램) (0) | 2024.07.20 |
[mybatis] 1. MYBATIS 개념 (0) | 2024.07.19 |