• iBATIS 인 액션
  • 쉽고 강력한 SQL 매핑 프레임워크 아이바티스

  • 클린턴 비긴 지음
  • 이동국, 손권남 옮김

  • 오픈소스 & 웹 시리즈 _ 002
  • ISBN: 9788995856437
  • 25,000원 | 2007년 05월 22일 발행 | 420쪽



iBATIS 창시자가 직접 쓴 종합 설명서

다른 복잡하고 배타적인 퍼시스턴스 솔루션들과는 달리, iBATIS는 객체 관계 매핑을 깔끔하고 간결하게 유지한다. 또 클래스를 SQL 구문에 매핑하고, 배우기 쉽고 친근한 퍼시스턴스 프레임워크이다. iBATIS의 접근 방식을 사용하면 애플리케이션에서 코딩하고 테스트하고 배포하기가 훨씬 수월해진다. 개발자가 기존과 같은 SQL을 작성하면 iBATIS가 데이터를 저장하거나 가져올 때 표준 객체를 사용할 수 있게 해준다. 기존의 데이터베이스 스키마를 변경할 필요는 전혀 없다. 또한 iBATIS는 레거시(심지어 잘못 설계된 것에서조차도 적용 가능한) 데이터베이스에 대해 아량이 넓은 프레임워크이다.

『iBATIS 인 액션』에서는 iBATIS의 창시자인 클린턴 비긴(Clinton Begin)이 직접 저자로 참여해서 iBATIS로 구현 가능한 모든 사항에 대해서 자세히 설명하고 있다. 프레임워크의 철학을 비롯하여 설정, 매핑 구문, 트랜잭션 등을 포함한 핵심 기능에 대해 자세하게 안내한다. 동적 SQL과 데이터 계층 추상화와 같은 복잡한 주제도 다루고 있다. 또 iBATIS 자체를 확장하는 유용한 기법도 배우게 될 것이다. 더이상 다른 책이나 자료를 찾아서 헤맬 필요가 없다.

『iBATIS 인 액션』에서는 다양한 예제를 활용하여 설명을 한다. 각 주제별 이슈에 대한 자세한 설명은 물론 다양한 예제가 제공되고 있고, 특히 14장에서 JGameStore라는 가상의 프로젝트를 통해 개발 프로세스 처음부터 끝까지에 대한 설명을 곁들이고 있어, 기존의 iBATIS 사용자는 물론 새로이 iBATIS를 도입하고자 하는 개발자들에게도 최선의 선택이 될 것이다.

Clinton Begin

클린턴 비긴은 캐나다 ThoughtWorks의 수석 개발자이며 iBATIS의 창시자이다.

Brandon Goodin

브랜든 구딘은 2003년부터 iBATIS 프로젝트에 공헌한 컨설턴트이다.

Larry Meadors

래리 메도스는 iBATIS 버전 1.x 때부터 개발에 참여한 컨설턴트이자 교육자이다.

이동국 http://openframework.or.kr/blog/

현재는 티맥스소프트 BPM 본부에 근무중이며, 주로 인터넷 상에서 프레임워크 관련 문서를 번역해서 올리면서 여러 사람에게 알려졌다. Spring 프레임워크 2.0 참조문서, iBATIS 튜토리얼 및 개발자 가이드, prototype.js 개발자 노트 그리고 AppFuse 한글문서 등을 작업했다. 또 마이크로소프트지에『ORM의 또 다른 핵 iBATIS SQL Maps』라는 기사를 기고하였으며, 한빛미디어의『Spring 프레임워크 워크북』 베타리더로도 활동했다. 현재 네이버의 ‘자바 프레임워크’ 카페의 스탭으로 활동하고 있다.

손권남 http://kwon37xi.egloos.com

NCSoft 산하 오픈 마루 스튜디오 웹 서비스팀에서 일하고 있다. 항상 공부하는 자세를 잃지않는 개발자가 되고자 한다. 자신의 블로그에 가끔씩 부질 없는 글을 올리기도 하며, 공부하다 기억할 만한 내용들을 정리해 두기도 한다.

1부 : 소개

  • 1장 iBATIS의 탄생 철학
    • 1.1 복합적인 솔루션 : 최고 중의 최고들로 구성하기
      • 1.1.1 iBATIS의 기원 답사
      • 1.1.2 iBATIS의 장점 이해하기
    • 1.2 iBATIS가 적합한 곳
      • 1.2.1 비즈니스 객체 모델
      • 1.2.2 프리젠테이션 계층
      • 1.2.3 비즈니스 로직 계층
      • 1.2.4 퍼시스턴스 계층
      • 1.2.5 관계형 데이터베이스
    • 1.3 여러 종류의 데이터베이스로 작업하기
      • 1.3.1 애플리케이션 데이터베이스
      • 1.3.2 기업용 데이터베이스
      • 1.3.3 독점적 데이터베이스(Proprietary Database)
      • 1.3.4 레거시 데이터베이스(Legacy Database)
    • 1.4 iBATIS는 데이터베이스의 공통적인 문제점들을 어떻게 다루나?
      • 1.4.1 소유권과 제어권
      • 1.4.2 여러 이종 시스템들에 의한 접근
      • 1.4.3 복잡한 키와 관계들
      • 1.4.4 비정규화된 혹은 과도하게 정규화된 모델
      • 1.4.5 빈약한 데이터 모델(Skinny Data Model)
    • 1.5 요약
  •  
  • 2장 iBATIS란 무엇인가?
    • 2.1 SQL 매핑하기
    • 2.2 어떻게 작동하나
      • 2.2.1 작고 간단한 시스템을 위한 iBATIS
      • 2.2.2 대규모 전사적 시스템을 위한 iBATIS
    • 2.3 왜 iBATIS를 사용하나?
      • 2.3.1 간단함
      • 2.3.2 생산성
      • 2.3.3 성능
      • 2.3.4 관심사의 분리
      • 2.3.5 작업의 분배
      • 2.3.6 이식성: 자바, .NET 그리고 그 외…
      • 2.3.7 오픈 소스와 정직성
    • 2.4 iBATIS를 사용하지 않는 경우
      • 2.4.1 개발자가 모든 것에 대해 영원한 결정권을 갖고 있을 때…
      • 2.4.2 애플리케이션이 완전히 동적인 SQL을 요구할 때
      • 2.4.3 관계형 데이터베이스를 사용하지 않을 때
      • 2.4.4 그냥 작동하지 않을 경우
    • 2.5 5분내에 사용 가능한 iBATIS
      • 2.5.1 데이터베이스 준비하기
      • 2.5.2 코드 작성하기
      • 2.5.3 iBATIS 설정하기(미리보기)
      • 2.5.4 애플리케이션 빌드하기
      • 2.5.5 애플리케이션 실행하기
    • 2.6 미래: iBATIS는 어디로 가는가?
      • 2.6.1 Apache 소프트웨어 재단
      • 2.6.2 더 간단하게, 더 작게, 더 적은 의존성으로
      • 2.6.3 더 많은 확장과 플러그인
      • 2.6.4 추가적인 플랫폼과 언어
    • 2.7 요약
    •  

2부 : iBATIS 기초

  • 3장 iBATIS의 탄생 철학
    • 3.1 iBATIS 배포판 얻기
      • 3.1.1 바이너리 배포판
      • 3.1.2 소스로부터 빌드하기
    • 3.2 배포판의 구성
    • 3.3 의존성
      • 3.3.1 적재 지연을 위한 바이트코드 확장
      • 3.3.2 Jakarta DBCP(Commons Database Connection Pool)
      • 3.3.3 분산 캐시(Distributed Cache)
    • 3.4 애플리케이션에 iBATIS 붙이기
      • 3.4.1 단독 실행 애플리케이션에서 iBATIS 사용하기
      • 3.4.2 웹 애플리케이션에서 iBATIS 사용하기
    • 3.5 iBATIS와 JDBC
      • 3.5.1 JDBC 리소스 해제하기
      • 3.5.2 SQL injection
      • 3.5.3 복잡도 낮추기
    • 3.6 계속되는 iBATIS 설정
      • 3.6.1 SQL Maps 설정 파일
      • 3.6.2 <properties> 요소
      • 3.6.3 <settings> 요소
      • 3.6.4 <typeAlias> 요소
      • 3.6.5 <transactionManager> 요소
      • 3.6.6 <typeHandler> 요소
      • 3.6.7 <sqlMap> 요소
    • 3.7 요약
  •  
  • 4장 매핑 구문으로 작업하기
    • 4.1 기본적인 사항들
      • 4.1.1 자바빈즈 생성하기
      • 4.1.2 SQL Map API
      • 4.1.3 매핑 구문의 타입들
    • 4.2 <select> 매핑 구문 사용하기
      • 4.2.1 # 대입자로 인라인 파라미터 사용하기
      • 4.2.2 $ 대입자로 인라인 파라미터 사용하기
      • 4.2.3 SQL 주입에 대한 간단한 예
      • 4.2.4 자동 결과 맵(Automatic result maps)
      • 4.2.5 관련된 데이터 조인하기
    • 4.3 매핑 파라미터
      • 4.3.1 외부 파라미터 맵
      • 4.3.2 인라인 파라미터 매핑 다시 보기
      • 4.3.3 원시타입 파라미터
      • 4.3.4 자바빈즈와 Map 파라미터
    • 4.4 인라인 결과 맵과 명시적인 결과 맵 사용하기
      • 4.4.1 원시타입의 결과(Primitive results)
      • 4.4.2 자바빈즈와 Map 형태타입의 결과
    • 4.5 요약
  •  
  • 5장 쿼리가 아닌(non-query) 구문 실행하기
    • 5.1 데이터 갱신을 위한 기초 다지기
      • 5.1.1 쿼리가 아닌(non-query) 구문을 위한 SQL Map API
      • 5.1.2 쿼리가 아닌(non-query) 매핑 구문
    • 5.2 데이터 삽입하기
      • 5.2.1 인라인 파라미터 매핑 사용하기
      • 5.2.2 외부 파라미터 맵 사용하기
      • 5.2.3 자동 생성 key
    • 5.3 데이터를 수정하고 삭제하기
      • 5.3.1 동시 수정 다루기
      • 5.3.2 자식 레코드를 수정하고 삭제하기
    • 5.4 일괄 업데이트 실행하기
    • 5.5 저장 프로시저로 작업하기
      • 5.5.1 장단점 고려하기
      • 5.5.2 IN, OUT, 그리고 INOUT 파라미터
    • 5.6 요약
  •  
  • 6장 고급 쿼리 기법
    • 6.1 iBATIS에서 XML 사용하기
      • 6.1.1 XML 파라미터
      • 6.1.2 XML로 결과 생성하기
    • 6.2 매핑 구문을 객체와 연관 시키기
      • 6.2.1 복잡한 컬렉션(collection)
      • 6.2.2 적재 지연(lazy loading)
      • 6.2.3 N 1 Select 문제 피해가기
    • 6.3 상속
      • 6.3.1 상속 매핑하기
    • 6.4 잡다한 다른 활용법들
      • 6.4.1 statement 타입과 DDL 사용하기
      • 6.4.2 매우 큰 데이터 셋 처리하기
    • 6.5 요약
  •  
  • 7장 트랜잭션
    • 7.1 트랜잭션은 무엇인가?
      • 7.1.1 간단한 은행 예제
      • 7.1.2 트랜잭션의 특성 이해하기
    • 7.2 자동 트랜잭션
    • 7.3 로컬 트랜잭션
    • 7.4 글로벌 트랜잭션
      • 7.4.1 능동(active) 혹은 수동(passive) 트랜잭션 사용하기
      • 7.4.2 트랜잭션을 시작하고 커밋하고 종료하기
      • 7.4.3 글로벌 트랜잭션이 필요한가?
    • 7.5 사용자 정의 트랜잭션
    • 7.6 트랜잭션 구분하기
      • 7.6.1 프리젠테이션 계층에서 트랜잭션 구분 짓기
      • 7.6.2 퍼시스턴스 계층에서 트랜잭션 구분 짓기
      • 7.6.3 비즈니스 로직 계층에서 트랜잭션 구분 짓기
    • 7.7 요약
  •  
  • 8장 동적인 SQL 사용하기
    • 8.1 동적인 WHERE 조건절 다루기
    • 8.2 동적 요소들과 친숙해지기
      • 8.2.1 <dynamic> 요소
      • 8.2.2 이항연산 요소
      • 8.2.3 단항연산 요소
      • 8.2.4 파라미터 요소
      • 8.2.5 <iterate> 요소
    • 8.3 모두 적용한 간단한 예제
      • 8.3.1 데이터를 가져오고 표시하는 방법을 정의하기
      • 8.3.2 데이터베이스 구조 결정하기
      • 8.3.3 정적인 형태로 SQL 작성하기
      • 8.3.4 동적인 SQL요소를 정적인 SQL에 적용하기
    • 8.4 고급 동적 SQL 기법
      • 8.4.1 결과 데이터 정의하기
      • 8.4.2 필수 입력 항목 정의하기
      • 8.4.3 정적인 형태로 SQL 작성하기
      • 8.4.4 동적 SQL 요소를 정적 SQL에 적용하기
    • 8.5 동적 SQL에 대안이 되는 접근법
      • 8.5.1 자바코드 사용하기
      • 8.5.2 저장 프로시저 사용하기
      • 8.5.3 iBATIS와 비교하기
    • 8.6 동적 SQL의 미래
      • 8.6.1 간단해진 조건 요소
      • 8.6.2 표현식(Expression Language)
    • 8.7 요약
  •  

3부 : iBATIS 실전

  • 9장 캐시를 통한 성능 향상
    • 9.1 간단한 iBATIS 캐싱 예제
    • 9.2 iBATIS의 캐싱에 관한 철학
    • 9.3 캐시 모델 이해하기
    • 9.3.1 type
      • 9.3.2 readOnly 속성
      • 9.3.3 serialize 속성
      • 9.3.4 readOnly와 serialize 조합
    • 9.4 캐시 모델 내부의 태그 사용하기
      • 9.4.1 캐시 비우기(Cache flushing)
      • 9.4.2 캐시 모델 구현체의 프라퍼티 설정하기
    • 9.5 캐시 모델 타입
      • 9.5.1 MEMORY
      • 9.5.2 LRU
      • 9.5.3 FIFO
      • 9.5.4 OSCACHE
      • 9.5.5 스스로 만든 캐시 모델
    • 9.6 캐싱 전략 수립하기
      • 9.6.1 읽기전용, 장기간 유지 데이터 캐싱
      • 9.6.2 읽기/쓰기 가능한 데이터 캐싱
      • 9.6.3 낡게 되는(aging) 정적 데이터 캐싱하기
    • 9.7 요약
  •  
  • 10장 iBATIS 데이터 접근 객체(DAO)
    • 10.1 상세한 구현 숨기기
      • 10.1.1 왜 분리하는가?
      • 10.1.2 간단한 예제
    • 10.2. DAO 설정하기
      • 10.2.1 <properties> 요소
      • 10.2.2 <context> 요소
      • 10.2.3 <transactionManager> 요소
      • 10.2.4 DAO 요소
    • 10.3 설정 팁들
      • 10.3.1 다중 서버
      • 10.3.2 다중 데이터베이스의 방언(dialect)
      • 10.3.3 실행 시에 설정 변경하기
    • 10.4 SQL Maps DAO 구현체 예제
      • 10.4.1. iBATIS를 사용하는 DAO 설정
      • 10.4.2. DaoManager 인스턴스 생성하기
      • 10.4.3 트랜잭션 관리자 설정하기
      • 10.4.4 맵 읽어들이기
      • 10.4.5 DAO 구현체 코딩하기
    • 10.5 요약
  •  
  • 11장 DAO 더 살펴보기
    • 11.1 SQL Maps가 아닌 DAO 구현체
      • 11.1.1. 하이버네이트 DAO 구현체
      • 11.1.2 JDBC DAO 구현체
    • 11.2 다른 데이터 소스로 DAO 패턴 사용하기
      • 11.2.1. 예제: LDAP로 DAO 사용하기
      • 11.2.2 예제: 웹 서비스로 DAO 사용하기
    • 11.3 Spring DAO 사용하기
      • 11.3.1 코드 작성하기
      • 11.3.2 왜 iBATIS 대신에 Spring을 사용하는가?
    • 11.4 개발자 스스로 DAO 계층을 생성하기
      • 11.4.1 구현체에서 인터페이스를 분리하기
      • 11.4.2 결합도 낮추기(decoupling)와 팩토리(factory) 생성하기
    • 11.5 요약
  •  
  • 12장 iBATIS 확장하기
    • 12.1 플러그인 가능한 컴포넌트 설계 이해하기
    • 12.2 사용자 정의 타입 핸들러로 작업하기
      • 12.2.1 사용자 정의타입 핸들러 구현하기
      • 12.2.2 TypeHandlerCallback 생성하기
      • 12.2.3 TypeHandlerCallback을 등록해서 사용하기
    • 12.3 CacheController 다루기
      • 12.3.1 CacheController 생성하기
      • 12.3.2 CacheController의 저장, 가져오기, 삭제하기
      • 12.3.3 CacheController를 등록해서 사용하기
    • 12.4 지원되지 않는 DataSource 설정하기
    • 12.5 사용자 정의 트랜잭션 관리
      • 12.5.1 TransactionConfig 인터페이스 이해하기
      • 12.5.2 Transaction 인터페이스 이해하기
    • 12.6 요약
    •  

4부 : iBATIS 활용하기

  • 13장 iBATIS 최적 활용기법
    • 13.1 iBATIS에서 단위 테스트하기
      • 13.1.1 매핑 계층 단위 테스트
      • 13.1.2 DAO 소비자 계층 단위 테스트 하기
    • 13.2 iBATIS 설정 파일 관리하기
      • 13.2.1 클래스패스 안에 두기
      • 13.2.2 파일들을 함께 두자
      • 13.2.3 리턴타입 별로 정리하라
    • 13.3 명명 규칙
      • 13.3.1 매핑 구문의 이름 짓기
      • 13.3.2 파라미터 맵의 이름 짓기
      • 13.3.3 결과 맵 이름 짓기
      • 13.3.4 XML 파일들
    • 13.4 빈즈, Map 혹은 XML?
      • 13.4.1 자바빈즈
      • 13.4.2 Map
      • 13.4.3 XML
      • 13.4.4 원시 타입(primitives)
    • 13.5 요약
  •  
  • 14장 모두 종합해서 만들어보기
    • 14.1 설계 컨셉
      • 14.1.1 계정
      • 14.1.2 카탈로그
      • 14.1.3 장바구니
      • 14.1.4 주문
    • 14.2 기술 선택
      • 14.2.1 프리젠테이션
      • 14.2.2 서비스
      • 14.2.3 퍼시스턴스
    • 14.3 Struts 조정하기: BeanAction
      • 14.3.1 BeanBase
      • 14.3.2 BeanAction
      • 14.3.3 ActionContext
    • 14.4 기초 닦기
      • 14.4.1 src
      • 14.4.2 test
      • 14.4.3 web
      • 14.4.4 build
      • 14.4.5 devlib
      • 14.4.6 lib
    • 14.5 web.xml 설정하기
    • 14.6 프리젠테이션 설정하기
      • 14.6.1 첫 번째 단계
      • 14.6.2 프리젠테이션 빈즈 이용하기
    • 14.7 서비스 작성하기
      • 14.7.1 dao.xml 설정하기
      • 14.7.2 트랜잭션 구분하기
    • 14.8 DAO 작성하기
      • 14.8.1 SQL Maps 설정
      • 14.8.2 SQL Map
      • 14.8.3 인터페이스와 구현체
    • 14.9 요약
  • 183쪽 중간

    만약 처음으로 내용을 생성하는 자식 요소가 prepend 속성을 갖고 있지 않은 경우에도, removeFirstPrepend 기능이 작동했다고 간주한다. 이 때문에 그 이후에 나오는 내용을 생성하는 요소가 prepend 속성을 가지고 있다면 그대로 prepend 속성값을 출력한다.

    => 아래와 같이 정정합니다.

    만약 처음으로 내용을 생성하는 자식 요소가 prepend 속성을 가지고 있지 않다면 removeFirstPrepend 기능을 수행하지 않은 걸로 간주한다. 그래서 그 이후에 내용을 생성하는 자식요소들 중 prepend 속성이 있을 때까지 removeFirstPrepend 제거 기능은 유효하고 이후 처음으로 나오는 prepend 속성에 대해 작동한다.

예제코드 관련 GitHub 페이지

관련 글