Dev/Struts

iBatis(2.0) 및 log4j 세팅

창문닦이 2019. 3. 20. 10:26

iBatis(버전2.0) 라이브러리 추가

iBatis는 DAO의 JDBC 형태를 보완하기 위해 나온 프레임워크이다. SQL에 기반한 데이터베이스와 자바를 연결해주는 역할을 해준다.

이렇게 데이터베이스와 관련된 작업을 정형화한 것들을 Persistence Framwork라 한다. 여기서 버전이 업그레이드 된 3.0이 Mybatis이다. iBatis와 Mybatis 둘의 차이점은 크진 않지만 추후에 비교해서 진행하고자 한다.


ibatis 프레임워크 사용을 위해 ibatis-2.3.4.726.zip의  jar파일을 lib폴더에 추가


1. 패키지 생성 및 SqlMapConfig 클래스 생성 

com.util.dao : 공통적으로 사용되는 DAO클래스를 생성

com.util.sqlMap : SqlMap.xml 환경설정 정보를 읽어 SqlMapClient 객체를 생성할 클래스

SqlMapConfig 클래스 생성

package com.util.sqlMap;

import java.io.IOException;

import java.io.Reader;

import com.ibatis.common.resources.Resources;

import com.ibatis.sqlmap.client.SqlMapClient;

import com.ibatis.sqlmap.client.SqlMapClientBuilder;

public class SqlMapConfig {

//final변수인데 초기화 없으면 오류.

private static final SqlMapClient sqlMap;

static{//static이므로 이미 메모리상에 올라가있음

try {

//해당위치에 있는 xml을 읽어서 sqlMap에 할당

String resource = "com/util/sqlMap/sqlMapConfig.xml";

Reader reader = Resources.getResourceAsReader(resource);

sqlMap = SqlMapClientBuilder.buildSqlMapClient(reader);

} catch (IOException e) {

e.printStackTrace();

throw new RuntimeException("Error initialixing class: "+ e);

}

}

public static SqlMapClient getSqlMapInstance() {

//이 메소드를 호출하면 메모리상에 올라가 있는 sqlMap 반환

return sqlMap;

}

}

2. sqlMapConfig.xml 생성 (환경설정 파일)

<!DOCTYPE sqlMapConfig

PUBLIC "-//ibatis.apache.org//DTD SQL Map Config 2.0//EN"

"http://ibatis.apache.org/dtd/sql-map-config-2.dtd">

이 부분에서 문법검사를 못하므로 오타가 나면 안됨!!

cacheModelsEnabled ▶ 캐시를 사용하지 않겠다

useStatementNamespaces 이름을 주고 그 이름인  com.board 를 호출해서 가져다가 쓰는 개념

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE sqlMapConfig

PUBLIC "-//ibatis.apache.org//DTD SQL Map Config 2.0//EN"

"http://ibatis.apache.org/dtd/sql-map-config-2.dtd">

<!-- Config(환경설정파일) -->

<sqlMapConfig>

<settings

cacheModelsEnabled="false"

useStatementNamespaces="true"/>

<!-- DB연결자. JDBC등록된 내용도 있고 이 내용도 함께 존재해야함 -->

<transactionManager type="JDBC" commitRequired="false">

<dataSource type="SIMPLE">

<property name="JDBC.Driver" value="oracle.jdbc.driver.OracleDriver"/>

<property name="JDBC.ConnectionURL"

value="jdbc:oracle:thin:@192.168.16.16:1521:TestDB"/>

<property name="JDBC.Username" value="SUZI"/>

<property name="JDBC.Password" value="A123"/>

</dataSource>

</transactionManager>

<!-- 이 sqlMap은 struts에서 struts-config_temp.xml를 만들어두고 복사해서 사용한것과 동일 -->

<sqlMap resource="com/util/sqlMap/temp_sqlMap.xml"/>

</sqlMapConfig>

3. temp_sqlMap.xml 생성

temp 파일을 만들어두고 템플릿처럼 복사 붙여넣기해서 사용할 것.

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE sqlMap

PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN"

"http://ibatis.apache.org/dtd/sql-map-2.dtd">

<!-- Mapper라고 함 -->

<sqlMap namespace="test">

SQL문 작성

</sqlMap>

제어의 역전(Ioc)과 의존성주입(DI) 

제어의 역전(Inversion of Control) :  컨테이너는 개발자가 작성한 코드를 컨트롤하여 객체의 생성과 소멸을 진행한다. 프레임워크의 동작원리를 일반적인 프로그램 흐름과 반대로 동작한다고 해서 제어의 역전이라고 부른다.

의존성 주입(Dependency Injection) : 객체 자체가 아니라 Framework에 의해 객체의 의존성이 주입되는 설계 패턴. 
생성자를 통한 주입, setter를 통한 주입, 멤버변수를 통한 주입이 있다.

1. SqlMapConfig클래스의 static변수

2. static변수 객체 생성시에 메모리상에 올라가면서 sqlMapConfig.xml을 읽어옴

3. sqlMapConfig.xml에 있는 마지막 문장의 xml파일들을 추가적으로 읽어옴

<sqlMap resource="com/util/sqlMap/temp_sqlMap.xml"/>

4. CommonDAO 인터페이스 생성

ibatis에만 존재. sql문이 실행되는 SQL문을 모든 경우의 수를 반영하여 생성해둔 것

package com.util.dao;

import java.sql.SQLException;

import java.util.List;

import java.util.Map;

public interface CommonDAO {

//데이터 추가

public void insertData(String id, Object value) throws SQLException;

//데이터 수정

public int updateData(String id, Object value) throws SQLException;

public int updateData(String id, Map<String, Object> map) throws SQLException;

//데이터 삭제

public int deleteData(String id) throws SQLException;

public int deleteData(String id, Object value) throws SQLException;

public int deleteData(String id, Map<String, Object> map) throws SQLException;

//해당 레코드 가져오기

public Object getReadData(String id) throws SQLException;

public Object getReadData(String id, Object value) throws SQLException;

public Object getReadData(String id, Map<String, Object> map) throws SQLException;

public int getIntValue(String id) throws SQLException;

public int getIntValue(String id, Object value) throws SQLException;

public int getIntValue(String id, Map<String, Object> map) throws SQLException;

public List<Object> getListData(String id) throws SQLException;

public List<Object> getListData(String id, Object value) throws SQLException;

public List<Object> getListData(String id, Map<String, Object> map) throws SQLException;

}

5. CommonDAOImpl 구현 클래스 생성

insert, update,delete의 경우 commit 작성해줘야 함을 유의!!

package com.util.dao;

import java.sql.SQLException;

import java.util.List;

import java.util.Map;

import com.ibatis.sqlmap.client.SqlMapClient;

import com.util.sqlMap.SqlMapConfig;

public class CommonDAOImpl implements CommonDAO {

private SqlMapClient sqlMap;

public CommonDAOImpl() {

//생성자에 의해 객체 초기화 될 수 있도록

this.sqlMap = SqlMapConfig.getSqlMapInstance();

}

public static CommonDAO getInstance(){

return new CommonDAOImpl();

}

@Override

public void insertData(String id, Object value) throws SQLException {

try {

sqlMap.startTransaction(); //트랜잭션 시작

sqlMap.insert(id,value); //insert문 실행

sqlMap.commitTransaction(); //트랜잭션 커밋

} catch (SQLException e) {

System.out.println(e.toString());

} finally {

sqlMap.endTransaction();//에러가 발생해도 트랜잭션을 종료시키게 작성

}

}

@Override

public int updateData(String id, Object value) throws SQLException {

int result = 0;

try {

sqlMap.startTransaction(); //트랜잭션 시작

result = sqlMap.update(id,value); //update문 실행

sqlMap.commitTransaction(); //트랜잭션 커밋

} catch (SQLException e) {

System.out.println(e.toString());

} finally {

sqlMap.endTransaction();//에러가 발생해도 트랜잭션을 종료시키게 작성

}

return result;

}

@Override

public int updateData(String id, Map<String, Object> map) throws SQLException {

int result = 0;

try {

sqlMap.startTransaction(); //트랜잭션 시작

result = sqlMap.update(id,map); //update문 실행

sqlMap.commitTransaction(); //트랜잭션 커밋

} catch (SQLException e) {

System.out.println(e.toString());

} finally {

sqlMap.endTransaction();//에러가 발생해도 트랜잭션을 종료시키게 작성

}

return result;

}

@Override

public int deleteData(String id) throws SQLException {

int result = 0;

try {

sqlMap.startTransaction();

result = sqlMap.delete(id);

sqlMap.commitTransaction();

} catch (SQLException e) {

System.out.println(e.toString());

} finally {

sqlMap.endTransaction();

}

return result;

}

@Override

public int deleteData(String id, Object value) throws SQLException {

int result = 0;

try {

sqlMap.startTransaction();

result = sqlMap.delete(id,value);

sqlMap.commitTransaction();

} catch (SQLException e) {

System.out.println(e.toString());

} finally {

sqlMap.endTransaction();

}

return result;

}

@Override

public int deleteData(String id, Map<String, Object> map) throws SQLException {

int result = 0;

try {

sqlMap.startTransaction();

result = sqlMap.delete(id,map);

sqlMap.commitTransaction();

} catch (SQLException e) {

System.out.println(e.toString());

} finally {

sqlMap.endTransaction();

}

return result;

}

@Override

public Object getReadData(String id) throws SQLException {

try {

//select문은 transaction start,endTransaction이 필요하지 않음

return sqlMap.queryForObject(id);

} catch (Exception e) {

System.out.println(e.toString());

}

return null;

}

@Override

public Object getReadData(String id, Object value) throws SQLException {

try {

//select문은 transaction start,endTransaction이 필요하지 않음

return sqlMap.queryForObject(id,value);

} catch (Exception e) {

System.out.println(e.toString());

}

return null;

}

@Override

public Object getReadData(String id, Map<String, Object> map) throws SQLException {

try {

//select문은 transaction start,endTransaction이 필요하지 않음

return sqlMap.queryForObject(id,map);

} catch (Exception e) {

System.out.println(e.toString());

}

return null;

}

@Override

public int getIntValue(String id) throws SQLException {

try {

return ((Integer)sqlMap.queryForObject(id)).intValue();

} catch (Exception e) {

System.out.println(e.toString());

}

return 0;

}

@Override

public int getIntValue(String id, Object value) throws SQLException {

try {

return ((Integer)sqlMap.queryForObject(id,value)).intValue();

} catch (Exception e) {

System.out.println(e.toString());

}

return 0;

}

@Override

public int getIntValue(String id, Map<String, Object> map) throws SQLException {

try {

return ((Integer)sqlMap.queryForObject(id,map)).intValue();

} catch (Exception e) {

System.out.println(e.toString());

}

return 0;

}

@SuppressWarnings("unchecked")

@Override

public List<Object> getListData(String id) throws SQLException {

try {

return (List<Object>)sqlMap.queryForList(id);

} catch (Exception e) {

System.out.println(e.toString());

}

return null;

}

@SuppressWarnings("unchecked")

@Override

public List<Object> getListData(String id, Object value) throws SQLException {

try {

return (List<Object>)sqlMap.queryForList(id,value);

} catch (Exception e) {

System.out.println(e.toString());

}

return null;

}

@SuppressWarnings("unchecked")

@Override

public List<Object> getListData(String id, Map<String, Object> map throws SQLException {

try {

return (List<Object>)sqlMap.queryForList(id,map);

} catch (Exception e) {

System.out.println(e.toString());

}

return null;

}

}



Log4J

Log4J : 자바 프로그램 작성 시 로그를 남기기 위해서 사용되는 Logging Framework

- apache 진영에서 나온 오픈소스 
- 로그 메시지를 콘솔, 텍스트파일, html파일, xml 파일, 이메일등으로 전송 가능 
- Logger(category) : 로그 파일을 작성하는 클래스, Appender 에 메시지를 전달 
- Appender : 로그를 출력하는 위치 
           (ex)ConsoleAppender, FileAppender..
- Layout : Appender 로 로그를 생성하기 전에 메시지의 형식을 만드는 클래스 

Log4J 설정파일
- log4j.properties(가장 사용하기 쉽고 직관적임)
- log4.xml
- java source 

Logger -- 로깅레벨
- DEBUG < INFO < WARN < ERROR < FATAL

Log4J 다운로드 : http://logging.apache.org/log4j/1.2/download.html


src 경로에 log4j.properties 파일 위치(소스 폴더 최상위)


lib 경로에 log4j-1.2.15.jar, commons-logging-1.1.1.jar 파일 복사

 
Appender Properties 
 - ConsoleAppender 옵션 
    # Threshold = WARN, category의 priority  가 더 낮게 설정되어 있다 하더라도 여기에 
                       명시된 priority 보다 낮은 메시지들은 로깅하지 않음 
    # ImmediateFlush = true, 로그메시지가 버퍼되지 않음, 기본값은 true
    # Target = System.err, 기본값은 System.out 

 - FileAppender 옵션 
   # Threshold = DEBUG
   # ImmdiateFlush = true
   # File = ./log/logfile.log, 로깅할 파일명 
   # append = false, 기본값은 true 이며, 파일끝에 추가 

 - RollingFileAppender 옵션 
    # Threadhold = WARN
    # ImmediateFlush = true
    # File = ./log/testlog.log
    # Append = false
    # MaxFileSize = 100KB(or MB, GB), 지정한 크기에 도달하면 로그파일을 교체 
    # MaxBackupIndex = 5, 최대 5개의 백업파일을 유지 
 
 - DailyRollingFileAppender 옵션 
    # Threadhold = WARN
    # ImmediateFlush = true
    # File = ./log/testlog.log
    # Append = false
    # DatePattern = ‘.’yyyy-mm, 매월 파일을 교체, 교체주기는 월, 주, 일,시간, 분 

Layout -- 표현식
%m = 로그 내용이 출력 
%p = debug, info, warn, error, fatal 등의 우선순위를 출력 
%r  = 어플리케이션이 시작되어 로깅이벤트가 발생하는 시점까지의 경과 
        시간을 밀리세컨드로 출력 
%c = logger 가 a.b.c 처럼 되어 있다면 %c{2} 는 b.c 가 출력 
%n = 플랫폼 종속적인 개행문자가 출력(\r\n 또는 \n)
%d = 로깅 이벤트가 일어난 날짜출력(프로그램의 실행속도를 느리게 함)
      ex) %d{HH:mm:ss} 또는 %d{dd MMMM yyyy HH:mm:ss}
%C = 호출자의 클래스명 출력 
      ex) org.apache.xyz.SomeClass 처럼 되어 있다면 %C{2}는 xyz.SomeClass 가 출력 
%M = 로깅이 발생한 method 이름을 출력 
%F = 로깅이 발생한 프로그램 파일명 출력 
%l = 로깅이 발생한 caller 의 정보를 출력 
%L = 로깅이 발생한 caller 의 라인수 출력 
%x = 로깅이 발생한 thread 와 관련된 NDC(nested diagnostic context) 를 출력 
%X = 로깅이 발생한 thread 와 관련된 MDC(mapped diagnostic context) 를 출력 
%% = %표시를 출력 
%t = 로그 이벤트가 발생한 쓰레드의 이름을 출력 


'Dev > Struts' 카테고리의 다른 글

Struts2 세팅  (0) 2019.03.21
Struts1/iBatis - 파일 업로드 기능 구현  (0) 2019.03.21
Struts1/iBatis - 게시판 만들기  (2) 2019.03.20
Struts1/JDBC - 게시판 만들기  (2) 2019.03.19
Struts1 세팅 및 기본 예제 & MVC 패턴  (0) 2019.03.18