Download presentation
Presentation is loading. Please wait.
1
목 차 iBATIS 탄생 철학 iBATIS 란? 설치와 설정 매핑 구문으로 작업하기
쿼리가 아닌(non-query) 구문 실행하기 고급 쿼리 기법 트랜잭션 동적인 SQL 사용하기 캐시를 통한 성능 향상 데이터 접근 객체(DAO) DAO 더 살펴보기 iBATIS 확장하기 iBATIS 최적 활용 기법
2
복합적인 솔루션 iBATIS의 탄생 철학 iBATIS의 기원답사 SQL 옛날식의 저장프로시져(Stored Procedure)
현대적인 저장 프로시저 인라인 SQL 동적 SQL 객체 관계 매핑
3
복합적인 솔루션 iBATIS의 탄생 철학 iBATIS의 장점 이해하기 외부로 뺀 SQL 캡슐화 된 SQL
방법 비슷한 이점 해결된 문제점 저장 프로시저 iBATIS는 SQL을 캡슐화하고 외부로 분리하여 애플리케이션 외부에 SQL을 둔다. iBATIS는 저장 프로시저와 비슷하지만 객체지향적인 API를 제공한다. iBATIS는 또한 저장 프로시저를 직접 호출하는 방법도 지원한다. 비즈니스 로직이 데이터베이스 밖에 있도록 한다. 배포하기 쉽다. 테스트하기 쉽다. 이식성이 좋다. 인라인 SQL iBATIS는 SQL을 원형 그대로 작성할 수 있다. 문자열 연결이나 파라미터 값 설정, 결과값 가져오기 등이 불필요하다. iBATIS는 애플리케이션 코드내에 삽입되지 않는다. 전처리기가 불필요하다. SQL의 일부가 아닌 모든 기능을 사용할 수 있다. 동적 SQL iBATIS는 파라미터를 기반으로 하여 동적으로 쿼리를 구성하는 기능을 제공한다. 쿼리구성 API는 필요없다. iBATIS는 애플리케이션 코드에 섞인 연결된 문자열 블록으로 SQL을 작성할 필요가 없다. 객체/관계 매핑 iBATIS는 ORM 도구의 적재 지연(lazy loading), 조인해서 값 가져오기(join fetching), 실시간 코드 생성, 상속 등과 같은 많은 기능들을 동일하게 제공한다. iBATIS는 어떠한 데이터 모델과 객체모델의 조합도 사용할 수 있다. 이들을 어떻게 설계 할지에 대한 제약이나 규칙 같은 것은 거의 없다. [다른 솔루션이 제공하는 것과 유사하게 iBATIS가 제공하는 장점] 외부로 뺀 SQL 캡슐화 된 SQL <select id=“categoryById” parameterClass=“string” resultClass=“category”> select categoryid, name, description from category where categoryid = #categoryId# </select>
4
iBATIS가 적합한 곳 iBATIS의 탄생 철학
계층화된 접근법 각 계층은 다른 계층에 대해 오직 제한된 정보만을 가질 수 있다. 오직 현재 계층에 인접한 계층에 대해서만… 스파게티 코드 – 계층화 되어 있지 않은 경우, 서로 다른 계층을 참조 [디미터 법칙(Law of Demeter)을 따르는 전형적인 계층화 전략] 비즈니스 객체모델 – 처리할 도메인을 객체지향적으로 묘사, 도메인 클래스, 데이터 전송 객체(DTO) 프리젠테이션 계층 비즈니스 로직 계층 – 서비스 클래스
5
iBATIS가 적합한 곳 iBATIS의 탄생 철학 퍼시스턴스 계층 - iBTIS가 존재하는 계층
- 저장소와 객체(데이터) 가져오기 추상계층 데이터 저장방식이 공통점이 없고 다양 -> 추상화가 필요 일관성있고 의미있는 인터페이스 제공, DAO 퍼시스턴스 프레임워크 데이터를 저장/조회/수정/검색/관리에 대한 메쏘드 제공 JDBC, ADO.NET 드라이버 혹은 인터페이스 저장소와 통신하는 소프트웨어 드라이버 [퍼시스턴스 계층의 내부적인 계층적 설계]
6
iBATIS가 적합한 곳 iBATIS의 탄생 철학 관계형 데이터베이스 무결성 - 성능 보안
7
여러 종류의 데이터베이스로 작업하기 iBATIS의 탄생 철학 애플리케이션 데이터베이스
[애플리케이션 데이터베이스 관계] 기업용 데이터베이스(Enterprise Database) [기업용 데이터베이스 아키텍처의 예제]
8
여러 종류의 데이터베이스로 작업하기 iBATIS의 탄생 철학 독점적 데이터베이스(Proprietary Database)
레거시 데이터베이스(Legacy Database)
9
iBATIS는 데이터베이스의 공통적인 문제점들을 어떻게 다루나?
소유권과 제어권 여러 이종 시스템들에 의한 접근 복잡한 키와 관계들 비정규화된 혹은 과도하게 정규화된 모델 빈약한 데이터모델(Skinny Data Model) [일반적인 형태의 주소 데이터] 소유권과 제어권 – DBA들이 실제 동작하는 SQL을 볼 수 있고, 심지어 iBATIS SQL파일을 직접 관리 여러 이종 시스템들에 의한 접근 트랜잭션, 배치처리, 리포팅 시스템 등을 포함한 모든 종류의 시스템에서 잘 동작 복잡한 키와 관계들 쿼리대 객체 매핑이므로 설계와 관계없이 가능.. [빈약한 데이터 모델 형태의 주소 데이터]
10
SQL 매핑하기 iBATIS란 무엇인가? iBATIS는 클래스를 테이블로 필드를 칼럼으로 직접 매핑하지 않는다.
[객체 관계 매핑] iBATIS는 클래스를 테이블로 필드를 칼럼으로 직접 매핑하지 않는다. 대신, SQL구문의 파라미터 결과를 클래스에 맵핑 교재 14페이지 예제를 통해 SQL 입력과 출력을 설명한다. [iBATIS SQL 매핑] [SQL은 입력과 출력으로 볼 수 있다.]
11
어떻게 작동하나? iBATIS란 무엇인가? 무엇보다도 iBATIS는 JDBC와 ADO.NET의 코드작성을 대신하는것!
JDBC를 이용한 어플리케이션과 iBATIS를 이용한 어플리케이션의 차이점 작고 간단한 시스템을 위한 iBATIS iBATIS 자체가 작고 간단하다. 375KB 이미 존재하는 어플리케이션이나 데이터베이스의 설계 변경 불필요 대규모 시스템에서도 잘 동작 대규모 전사적 시스템을 위한 iBATIS 데이터베이스 또는 객체 모델의 설계에 어떠한 전제도 하지 않음. 매우 큰 데이터 셋을 효율적으로 다룰 수 있는 기능 Row Handler, Lazy Loading … 데이터베이스 객체를 다양한 방법으로 매핑 코드가 아닌 설정
12
왜 iBATIS를 사용하나? iBATIS란 무엇인가? 간단함 iBATIS의 설계 목표의 핵심, 가장 높은 우선순위 생산성
62% <- JDBC 코드 성능 loop를 통한 단순 성능 -> JDBC 많은 성능 최적화 기법을 지원 정확성 - 잘못 작성된 JDBC 코드 -> 성능감소 관심사의 분리 ResultSet이 아닌, 실체객체를 가지고 작업 계층화를 위한하는것이 힘들어짐. 작업의 분배 SQL이 소스코드로부터 완전 분리 DBA와의 작업분배 이식성 : 자바, .NET 그리고 그외… 오픈 소스와 정직성
13
iBATIS를 사용하지 않는 경우 iBATIS란 무엇인가?
개발자가 모든 것에 대해 영원한 결정권을 갖고 있을 때 패키지 소프트웨어 제품 -> Hibernate와 같은 완전한 ORM 솔루션 애플리케이션이 완전히 동적인 SQL을 요구할 때 대부분의 SQL구문이 SQL Generator등을 통해 동적으로 생성되는 경우 관계형 데이터베이스를 사용하지 않을 때 일반 파일, 엑셀, XML - 그냥 작동하지 않을 경우 복잡한 요구사항에 의해 iBATIS가 맞지 않는 경우
14
5분 내에 사용 가능한 iBATIS iBATIS란 무엇인가? 데이터베이스 준비하기
MySQL 설치 ~\tools\Mysql JDBC 드라이버 예제를 위한 db구성 – 스크립트 실행 코드 작성하기 Test Application ~\workspace\ iBATIS 설정하기 SQL Maps 설정 SqlMapConfig.xml, SqlMap.xml 애플리케이션 빌드하기 애플리케이션 실행하기
15
미래 : iBATIS는 어디로 가는가? iBATIS란 무엇인가? Apache 소프트웨어 재단
더 간단하게, 더 작게, 더 적은 의존성으로 Annotation 지원 개발 도구 더 많은 확장과 플러그인 추가적인 플랫폼과 언어 Java, .NET, Ruby + PHP 5, Python
16
iBATIS 배포판 얻기 iBATIS의 설치와 설정 바이너리 배포판 소스로부터 빌드하기
ibatis-common-2.jar, ibatis-sqlmap-2.jar ibatis jar 소스로부터 빌드하기 저장소 파헤치기 – 디렉토리 목 적 Build 프레임워크를 컴파일 하는 데 사용하는 Ant 스크립트가 있고 컴파일 결과들도 모두 여기에 저장된다. Devlib Apache 프로젝트에 속하면서 컴파일에 필요한 것들이 이 디렉토리에 있다. Devsrc Apache 프로젝트에 속하지 않거나 저장소에 저장하기에는 너무 큰 프로젝트들 중 컴파일 시에 필요한 것들. 정상적으로 컴파일하기 위해 마치 API처럼 보이는 가짜 소스를 저장소에 두고 iBATIS를 컴파일 하는데 사용한다. Doc 프로젝트 문서를 저장하고 있는 곳이다. Javadoc Javadoc은 API문서를 소스 코드의 doc 주석으로부터 HTML형식으로 생성해 주는 것이다. 그리고 빌드 과정에 필요한 설정 예제 파일들도 있다. Src 프레임워크의 실제 코드가 있는 곳이다. Test 단위 테스트(unit test)는 코드의 정확성을 테스트하는 한 가지 방법이다. iBATIS 프레임워크는 배포판 빌드 과정에서 자동화된 단위테스트를 위해 Junit을 사용한다. 빌드 과정에서 테스트들을 실행하고 그 결과에 대한 보고서를 생성할 것이다. tools iBATIS로 작업하는 데 유용한 도구들이 있다. 예를 들어 Abator도 이 디렉토리에 있다. iBATIS는 간결함을 기초로 만들어졌다. JDBC, XML, SQL에만 익숙하다면 배워야 할 것이 별로 많지 않다. 바이너리 배포판 두개의 jar로 나뉘어 있던것이, 2.3을 기존으로 하나로 통합되었다. 또한, 특별한 기능을 사용할 때 필요한 부가적인 JAR파일이 필요하나 어떤 써드파티 라이브러리도 필요하지 않다. <- 의도적임. 간결성 유지 빌드 수행하기
17
배포판의 구성 iBATIS의 설치와 설정 iBATIS 2.3.4 GA Release, 2008/09/19 파일 목적
/lib/ibatis jar 프레임워크 모두가 사용하는 공통 컴포넌트들과 SQL Maps 프레임워크의 컴포넌트들을 포함하고 있는 파일이다. /doc/user-javadoc.zip iBATIS 자체를 개발하는 개발자가 아닌, iBATIS 프레임워크를 사용해서 개발을 하는 사용자들을 위해 필요한 것만 모아둔 JavaDoc 문서이다. /doc/dev-javadoc.zip iBATIS 프로젝트의 모든 JavaDoc 문서를 포함하고 있는 파일이다. /src/ibatis-src.zip 프레임워크의 JAR파일을 빌드하는데 사용된 전체 소스를 포함하고 있는 파일이다.
18
Dependencies iBATIS의 설치와 설정 Lazy Loading을 위한 바이트코드 확장
1000 clients X 1000 orders X 25 items = 25,000, > 25! Jakarta DBCP(Commons Database Connection Pool) Connection Pool Vendor간 다양성 존재 분산 캐시(Distributed Cache) OpenSymphony – OSCache iBATIS의 기본기능 이외에 부가 기능을 사용하기 위해선 다른 오픈소스 혹은 상용 패키지가 필요하며, 의존성 문제를 해결해야 함. 여기서는 이러한 확장기능들에 대해서 간단한 개요만 보고 뒤 절들에서 자세하게 다룬다. JDBC는 어떤 JDBC드라이버라도 쉽게 커넥션 풀로 사용할 수 있도록 해주는 Wrapper OSCache – 다중 서버를 클러스터링하도록 설정 확장성(scalability)과 오류복구(fail over)기능을 제공해준다.
19
애플리케이션에 iBATIS 설정하기 iBATIS의 설치와 설정 단독 실행 애플리케이션에서 iBATIS 사용하기
CLASSPATH 환경변수(Environment Variable) JRE – lib/ext 단독 실행 애플리케이션에서 iBATIS 사용하기 -cp option 웹 애플리케이션에서 iBATIS 사용하기 WEB-INF/lib WAS의 공유디렉토리 tomcat의 경우 shared/lib, common/lib 에 대한 사용은 일반적으로 권장되지 않는다. 서로 다른 classloader에 의해 적재된 class는 서로 다른 클래스로 간주. 예외) JNDI DadaSource를 사용하는 JDBC드라이버는 사용한다. 서버 로딩시 connonection pool을 사용해야 하므로..
20
iBATIS와 JDBC iBATIS의 설치와 설정 JDBC JDBC 리소스 해제하기 – Garbage Collection
자바프로그래밍 언어의 데이터베이스 접속에 관한 표준 MS ODBC API -> JDBC 1.1, 1997 JDBC 2.0, 1999 JDBC 3.0, 2002 JDBC 4.0, 2006 JDBC 리소스 해제하기 – Garbage Collection SQL 주입(injection) select * from product where id = ‘5’ -> select * from product where id = ‘5’; delete from orders 복잡도 낮추기 – 저수준의 API로 부터 Connection conn = null; try { conn = dataSource.getConnection(); JDBC Release 복잡도 낮추기(Reducing the complexity) JDBC 코딩 sample하나 살펴보기
21
계속되는 iBATIS 설정 iBATIS의 설치와 설정 아래 상세 설명에 대해서 예제를 살펴보아야 한다.
Properties 아래 상세 설명에 대해서 예제를 살펴보아야 한다. SQL Maps 설정파일 SqlMapConfig.xml(파일명 변경 가능) iBATIS 전체 옵션 설정 <settings /> 각각의 SQL Map파일들의 위치 지정<sqlMap> 어플리케이션의 DB와 소통하기 위해 제공되는 입력파라미터 값과 조합되는 매핑구문을 정의 <transactionManager> 다음 장에서 SqlMapConfig.xml 파일의 요소들을 하나하나씩 살펴보자. 그 요소들은 결국 dtd에 있다. The SQL Map can have a single <properties> element [SqlMapConfig를 설정의 최상단에 두고 본 iBATIS 설정의 핵심 개념]
22
계속되는 iBATIS 설정 iBATIS의 설치와 설정 SQL Maps 설정파일 <properties> 요소
설정의 일반화를 위해 이름/값 쌍의 리스트를 제공 속성 resource – classpath상의 resource 또는 file, file system, jar url – Uniform Resource Locator(URL), java.net.URL <properties url=”file:///c:/config/my.properties” /> driver=org.hsqldb.jdbcDriver <property name="JDBC.Driver" value="${driver}"/> <settings> 요소 classInfoCacheEnabled:true lazyLoadingEnabled:true statementCachingEnabled:true cacheModelsEnabled:true enhancementEnabled:false errorTracingEnabled useStatementNamespaces:false useColumnLabel:true forceMultipleResultSetSupport defaultStatementTimeout maxRequest: 2.3.1에서 제거 maxSessions: : 2.3.1에서 제거 maxTransaction: : 2.3.1에서 제거, -1 교재 7 - <Properties> 교재 8 - <settings> 꼭 파일을 참조하면서 이해하자.. <properties> element 오직 한 개만 설정 가능 <- dtd로부터 다른 개발 도구들의 프로퍼티 설정과 동일하다. 예제를 통해 알아보자. a=b -> ${a} -> b <settings> element 잡동사니 설정 옵션 The settings element and all of its attributes are completely optional. maxRequests 이것은 한꺼번에 SQL문을 수행할수 있는 쓰레드의 수이다. 셋팅값보다 많은 쓰 레드는 다른 쓰레드가 수행을 완료할때까지 블록된다. 다른 DBMS는 다른 제한 을 가진다. 이것은 최소한 10개의 maxTransactions이고 언제나 maxSessions과 maxTransactions보다 크다. 종종 동시요청값의 최대치를 줄 이면 성능향상을 보여준다. 예: maxRequests=”256” Default: 512 maxSessions 이것은 주어진 시간동안 활성될수 있는 세션의 수이다. 세션은 명시적으로 주어 질수도 있고 프로그램적으로 요청될수도 있고 쓰레드가 SqlMapClient인스턴스 를 사용할때마다 자동적으로 생성될수도 있다. 이것은 언제나 maxTransaction보다 같거나 커야 하고 maxRequests보다 작아야 한다. 동시 세션값의 최대치를 줄이면 전체적인 메모리사용량을 줄일수 있다. maxSessions=”64” Default: 128 maxTransactions 이것은 한꺼번에 SqlMapClient.startTransaction()에 들어갈수 있는 쓰레드 의 최대갯수이다. 셋팅값보다 많은 쓰레드는 다른 쓰레드가 나올때까지 블록된 다. 다른 DBMS는 다른 제한을 가진다. 이 값은 언제나 maxSessions보다 작 거나 같아야 하고 maxRequests보다 작아야 한다. 종종 동시트랜잭션의 최대 치를 줄이면 성능향상을 보여준다. maxTransactions=”16” Default: 32
23
계속되는 iBATIS 설정 iBATIS의 설치와 설정 <typeAlias> 요소_1
<typeAlias> element 완전한 형태의 클래스 이름(FQCN, Fully Qualified Class Name) 대신 사용 예제를 통해 확인해 보자. Ex) <typeAlias alias=“Account” type=“org.apache.ibatis.jgamestore.domain.Account” /> [몇몇 매우 긴 클래스명을 적는 시간을 아껴줄 데이터 타입의 기본 내장 별칭 정의들]
24
계속되는 iBATIS 설정 iBATIS의 설치와 설정 <typeAlias> 요소_2
[몇몇 매우 긴 클래스명을 적는 시간을 아껴줄 데이터 타입의 기본 내장 별칭 정의들]
25
계속되는 iBATIS 설정 iBATIS의 설치와 설정 <transactionManager> 요소
이름 설명 JDBC 간단한 JDBC 기반 트랜잭션 관리 기능을 제공한다. 대부분의 경우 이것으로 충분하다. JTA 컨테이너에 기반한 트랜잭션 관리 기능을 애플리케이션에 제공한다. EXTERNAL 트랜잭션 관리자를 제공하지 않고 iBATIS 대신 애플리케이션이 직접 트랜잭션을 관리한다고 가정한다. [기본 내장 트랜잭션 관리자] <property> 요소 각 Transaction Manager별로 다른 옵션 설정 EXTERNAL – DefaultAutoCommit, SetAutoCommitAllowed JTA - UserTransaction <dataSource> 요소 이름 설명 SIMPLE Simple 데이터 소스 팩토리는 말 그대로 단순하다. 간단한 커넥션 풀을 내장한 데이터 소스를 설정하고자 할 때 이를 사용하며, iBATIS 프레임워크는 실제 JDBC 드라이버만 빼고 데이터 소스에 필요한 모든 것을 자체 내장하고 있다. DBCP DBCP 데이터 소스 팩토리는 Jakarta Commons Database Connection Pool 구현을 제공한다. JNDI JNDI 데이터 소스 팩토리는 JNDI를 통해 할당된 컨테이너 기반의 데이터 소스를 공유하도록 사용된다. 교재 10 ~ 11 <transactionManager> 교재 11 <property> 교재 11 ~ 13 <dataSource> 교재 13 <sqlMap> [데이터 소스 팩토리] <typeHandler> 요소 사용자정의 타입 핸들러 – jdbcType <-> javaType <sqlMap> 요소 P13
26
기본적인 사항들 매핑 구문으로 작업하기 자바빈즈 생성하기 어떻게 빈즈를 만드나? 빈즈 탐색
[자바빈즈 프로퍼티명과 메소드 예제] 자바빈즈에 대한 iBATIS in action 책의 89 ~ 92의 내용을 예제로 만들어 보자. 빈즈 탐색 [빈즈 탐색 예제]
27
기본적인 사항들 매핑 구문으로 작업하기 SQL Map API iBATIS가 제공하는 API
SqlMapClient 인터페이스가 제공하는 메소드들… queryForObject()메소드 queryForList() 메소드 queryForMap() 메소드 소스에서 SqlMapExecutor, SqlMapClient를 살펴보자 Javadoc에서 com.ibatis.sqlmap.client 부분을 확인. 아래 내용에 대해서 언급한다.. public interface SqlMapClient extends SqlMapExecutor, SqlMapTransactionManager {
28
기본적인 사항들 매핑 구문으로 작업하기 매핑 구문의 타입들 교재 15 ~ 16 구문타입별 실행가능한 쿼리가 나와있다.
속성 자식요소 사용하는 경우 <select> id parameterClass resultClass parameterMap resultMap cacheModel 모든 동적인 요소 데이터 조회 <insert> id parameterClass parameterMap 데이터 입력 <delete> 데이터 삭제 <procedure> id parameterClass resultClass parameterMap resultMap xmlResultName 저장 프로시져 호출 <statement> xmlResultName 거의 모든것을 실행하는 데 사용할 수 있는 쿼리 구문 모두 교재 15 ~ 16 구문타입별 실행가능한 쿼리가 나와있다. <sql>과 <include> 를 이용한 예제를 실행해보자. - SqlMap.xml에서 ‘매핑구문의 타입들 예제’ - 예제 내에서 sql의 내용중 where 절에서 > < 를 표한하기 위해 <![CDATA[ > ]]> 를 사용한 부분에 유의하자! 교재 16에서도 언급하고 있다. 구문타입 속성 자식요소 사용하는 경우 <sql> id 모든 동적인 요소 매핑 구문은 아니지만 매핑 구문 내에서 사용될 수 있는 컴포넌트를 만들기 위해 사용 <include> refid 없음 매핑 구문은 아니지만 매핑 구문에 <sql> 타입으로 생성된 컴포넌트를 삽입하기 위해 사용
29
<select> 매핑 구문 사용하기
매핑 구문으로 작업하기 # 대입자(placeholders)로 인라인 파라미터 사용하기 매핑구문 찾기 -> #xxx# 대입자를 PreparedStatement 파라미터로 변환 WHERE 절에서 LIKE를 어떻게 사용하는가? 문자열 대체문법($ 대입자) $ 대입자로 인라인 파라미터 사용하기 SQL 주입에 대한 간단한 예 자동 결과 맵(Automatic result maps) Result Map, Result Class -> 단일칼럼, 고정 칼럼목록, 동적 칼럼목록 둘 다 제공하지 않는다면? DB에는 존재하지만, 매핑하는 빈즈에는 존재하지 않는다면? 관련된 데이터 조인하기 단일 테이블 조회와 다를바가 없다. 교재 15 ~ 16 구문타입별 실행가능한 쿼리가 나와있다. <sql>과 <include> 를 이용한 예제를 실행해보자. SqlMap.xml에서 ‘매핑구문의 타입들 예제’ 교재 17 LIKE 연산 예제를 살펴보자 #대입자와 $대입자의 차이를 이해하고 LIKE 연산 예제를 이용해 SQL Injection에 대한 예제는 실제 동작하지 않았다.
30
매핑 파라미터 매핑 구문으로 작업하기 인라인 파라미터 맵과 외부 파라미터 맵 외부 파라미터 맵 iBATIS에서 파라미터 맵핑은
속성 설명 property 파라미터 맵의 property 속성은 매핑 구문에 전달되는 자바빈즈의 프로퍼티 이름이거나 Map의 키 이름이다. 이 이름은 매핑 구문 안에서 한번 이상 필요한 대로 사용할 수 있다. 예를 들어 같은 property가 SQL update 구문의 SET 절에서 수정되고 WHERE 절에서 key의 일부로 사용된다면, 이 이름은 매핑 구문에서 두 번 참조될 수 있다. javaType javaType속성은 파라미터의 자바 프로퍼티 타입을 명시적으로 지정하는 역할을 한다. 대개 리플렉션을 통해 자바빈즈 프로퍼티의 타입을 알아 낼 수 있지만 Map과 XML매핑과 같은 경우에는 프레임워크가 프로퍼티의 타입을 알아낼 수 없다. 이러한 경우 javaType이 셋팅되지 않고 프레임워크도 그 타입을 판단할 수 없다면, 타입은 Object 타입으로 간주된다. jdbcType jdbcType 속성은 파라미터의 데이터베이스 타입을 명시하는데 사용한다. 몇몇 JDBC 드라이버는 드라이버에 칼럼타입을 알려주지 않으면 칼럼의 타입을 알아내지 못한다. 이에 대한 완벽한 예제로 PreparedStatement.setNull(int parameterIndex, int sqlType)가 있다. 이 메소드에는 타입을 명시해야 한다. 몇몇 드라이버는 Types.OTHER나 Types.NULL을 보내서 암시적인 타입을 허용할 것이다. 일관되게 특정 타입으로 유지되지 않고 경우에 따라 다른 타입으로 작동할 수도 있기 때문에 어떤 드라이버를 사용할때는 정확한 타입으로 명시할 필요가 있게 된다. 이러한 상황을 위해, iBATIS는 parameterMap 프로퍼티 요소의 jdbcType 속성을 사용하여 타입을 지정할 수 있도록 하고 있다. 이 속성은 대개 칼럼을 null로 설정할 때만 필요하다. 타입 속성을 사용하는 다른 이유는 자바 타입이 모호할 때 데이터 타입을 확실히 명시하고자 함이다. 예를 들어, 자바에는 오직 한가지 날짜 타입(java.util.Date)만이 있지만, 대부분의 SQL 데이터베이스에는 적어도 세 개의 관련 타입이 있다. 이것 때문에 칼럼타입이 DATE인지 혹은 DATETIME인지 명시해야 할 수도 있다. jdbcType 속성은 JDBC의 types 클래스(java.sql.Types)에 있는 상수와 일치하는 모든 문자열로 설정할 수 있다. nullValue nullValue 속성은 프로퍼티 타입에 기초하여 어떤 유효한 값으로 라도 설정할 수 있다. nullValue속성은 DB로 보내지는 null값을 대신하는데 사용한다. 이것은 자바빈즈나 Map 항목에서 이 값을 만난다면, NULL이 데이터베이스에 기록된다는 의미(db에서 결과를 가져올 때의 null값 대체의 행위와 반대되는)이다. 이를 통해 null값을 지원하지 않는 타입(이를테면 int, double, float 기타 등등)을 위해 애플리케이션 내에서 매직 null 넘버(magic null number)를 사용할 수 있게 된다. 이러한 타입의 프로퍼티가 null로 지정된 값(이를테면, -9999)과 일치하면 그 값 대신에 NULL을 데이터베이스에 기록한다. iBATIS에서 파라미터 맵핑은 인라인 파라미터 맵핑과 외부 파라미터 맵핑이 존재 대부분의 경우 인라인 파라미너 매핑은 잘 작동하나 - 성능향상 - 인라인 파라미터 맵핑이 기대한 것과 다르게 동작하는 경우 외부 파라미터 매핑이 필요하다. [파라미터 매핑 속성]
31
매핑 파라미터 매핑 구문으로 작업하기 인라인 파라미터 매핑 다시 보기 – 교재 25 자바빈즈와 Map 파라미터
속성 설명 mode 이 속성은 저장 프로시저 지원을 위해서만 사용된다 typeHandler 타입 핸들러(javaType과 jdbcType 속성에 기반하여 iBATIS가 선택하는 것 대신에)를 명시하고자 한다면, 이 속성을 사용하면 된다. 대개, 이것은 사용자 정의 타입 핸들러를 지정하는 데 사용한다. [파라미터 매핑 속성] 인라인 파라미터 매핑 다시 보기 – 교재 25 #[파라미터 이름]:[데이터 타입]:[null값]# #[파라미터 이름],jdbcType=[데이터 타입]# 자바빈즈와 Map 파라미터 빈즈를 이용한 파라미터 맵 Map을 이용한 파라미터 맵 인라인 파라미터 맵에서의 데이터 타입 지정방법 2가지 예제를 살펴보자. SQL Map은 XML이므로 < 대신 <, > 대신 > 을 사용하거나, CDATA를 사용해야 하나, 동적 SQL 사용시 제대로 동작하지 않을 수 있다. 원시타입 파라미터에 대한 건 생략했다. 자바빈즈와 Map 파라미터 둘의 차이점은 파라미터 맵을 적재할때 잘못된 파라미터 참조에 대해서 알 수 있냐 없냐의 차이다. 예제 :
32
인라인 결과 맵과 명시적인 결과 맵 사용하기 매핑 구문으로 작업하기 속성 설명 property
결과 맵의 property 속성은 매핑 구문이 반환할 결과 객체 자바빈즈의 프로퍼티 이름이거나 Map의 키이다. 이 이름은 매핑 구문 안에서 한 번 이상 필요한 대로 사용할 수 있다. column column 속성을 이용해서 property의 값으로 사용할 ResultSet의 칼럼명을 지정한다. columnIndex 조금(최소한)이라도 성능향상을 원한다면, columnIndex 속성을 이용해서 칼럼 이름 대신에 ResultSet 내의 칼럼 순서를 지정 할 수도 있다. 이는 99%의 애플리케이션에서 불필요한 것이며, 이를 사용하면 성능 때문에 유지 보수성과 가독성을 희생시키는 것이 된다. JDBC드라이버에 따라 성능 향상이 있을 수도 잇고 없을 수도 있다. jdbcType jdbcType속성은 property값으로 사용될 ResultSet 칼럼의 데이터베이스 칼럼타입을 명시하는데 사용한다. 비록 결과 맵에서는 파라미터 맵에서처럼 null값과 같은 어려움이 없다고 하더라도, 타입을 명시하면 Date 프로퍼티와 같은 몇몇 매핑 타입에서 쓸만한 역할을 할 수 있다. 자바는 하나의 Date타입만 있지만, SQL데이터베이스에는 여러 개(일반적으로 적어도 3개)가 있기 때문에, 날짜 (혹은 다른타입)값을 정확하게 지정하고자 한다면 날짜를 정확하게 명시할 필요가 있다. 이와 유사하게 VARCHAR, CHAR 또는 CLOB는 문자열을 생성한다. 그래서 이 경우에도 타입을 명시할 필요가 있다. 사용하는 드라이버에 따라 이 속성을 설정할 필요가 없을 수도 있다. javaType javaType 속성을 사용하여 결과 값을 저장할 프로퍼티의 자바 타입을 명시적으로 지정한다. 대개 리플렉션을 통해 자바빈즈 프로퍼티의 타입을 알아 낼 수 잇지만, Map과 XML매핑과 같은 경우에는 프레임워크가 프로퍼티의 타입을 알아낼 수 없다. javaType이 지정되지 않고 프레임워크가 그 타입을 판단할 수 없다면, Object 타입으로 간주한다. nullValue nullValue 속성에 데이터베이스의 NULL값을 대체하기 위해 사용되는 값을 명시한다. 그래서 Resultset으로부터 NULL을 읽었다면, 자바빈즈 프로퍼티는 NULL대신에 nullValue속성에 명시된 값으로 지정될 것이다. Null 속성 값은 어떠한 값도 될 수 있지만 해당 프로퍼티 타입에 유효한 값이어야 한다. select select 속성을 통해서 iBATIS가 혼합(이를테면, 사용자가 정의한)프로퍼티 타입을 자동으로 적재할 수 있도록 객체 간의 관계를 서술한다. 매핑 구문 프로퍼티의 값은 다른 매핑 구문의 이름이어야 한다. 매핑 구문 속성과 동일한 property요소에서 정의하는 데이터베이스 칼럼의 값(column속성)은 관련된 매핑 구문에 파라미터로 전달될 것이다. 따라서 해당 칼럼이 꼭 지원되야 하며, 원시타입이어야 한다. [결과 맵 속성]
33
인라인 결과 맵과 명시적인 결과 맵 사용하기 매핑 구문으로 작업하기 원시타입의 결과(Primitive results)
Java에서의 원시타입 – boolean, char, byte, short, int, long, float, double Wrapper Class – Boolean, Char, Byte, Short, Integer, Long, Float, Double 예제 – 원시타입의 결과 자바빈즈와 Map타입의 결과 접근 방식 장점 단점 자바빈즈 성능 컴파일 시 강력한 타입 검사 컴파일 시 이름 검사 IDE에서의 리팩토링 지원 형변환이 줄어듬 코드량의 증가(get/set) Map 코드량의 감소 느림 컴파일 시 검사하지 않음 약한 타입 실행시 오류 발생이 잦음 리팩토링 지원 없음 예제 원시타입의 결과를 통해 알아보자. [데이터 구조로서의 자바빈즈와 Map의 장점과 단점] 빈즈 - 도메인 데이터 Map – 덜 중요, 더 동적인, 리포트 등
34
데이터 갱신을 위한 기초 다지기 쿼리가 아닌(non-query) 구문 실행하기
쿼리가 아닌 (non-query) 구문을 위한 SQL Map API insert 메소드 Object insert(String id, Object parameterObject) throws SQLException; 객체(Object)를 반환하는 이유? <selectKey> update 메소드 int update(String id, Object parameterObject) delete 메소드 int delete(update(String id, Object parameterObject)
35
데이터 갱신을 위한 기초 다지기 쿼리가 아닌(non-query) 구문 실행하기 쿼리가 아닌(non-query) 매핑 구문
구문타입 속성 자식요소 사용하는 경우 <insert> id parameterClass parameterMap 모든 동적인 요소 <selectKey> 데이터 입력 <update> 데이터 수정 <delete> 데이터 삭제 <procedure> resultClass resultMap xmlResultName 저장 프로시저 호출 <sql> 매핑 구문은 아니지만 매핑 구문 내에서 사용될 수 있는 컴포넌트를 만들기 위해 사용 <include> refid 없음 매핑 구문은 아니지만 매핑 구문에 <sql>타입으로 생성된 컴포넌트를 삽입하기 위해 사용 [데이터를 갱신하는 데 사용하는 매핑 구문(그리고 관련된 XML요소)]
36
데이터 삽입하기 쿼리가 아닌(non-query) 구문 실행하기 인라인 파라미터 매핑 사용하기 예제 – 데이터 삽입하기
외부 파라미터 맵 사용하기 자동 생성 Key <selectKey>는 pre-generated key(oracle)와 post-generated key(ms-sql)를 모두 지원한다. 예제 – 자동 생성 키
37
데이터를 수정하고 삭제하기 쿼리가 아닌(non-query) 구문 실행하기 동시 수정 다루기 자식 레코드를 수정하고 삭제하기
38
일괄 업데이트 실행하기 쿼리가 아닌(non-query) 구문 실행하기 예제 – 일괄 업데이트 실행하기
39
저장 프로시저로 작업하기 쿼리가 아닌(non-query) 구문 실행하기 장,단점 고려하기
극단적이 되지 말라! 작업에 맞는 도구 사용하기 IN,OUT 그리고 INOUT 파라미터 IN – 다른 매핑 구문과 동일 자바순수주의자 – 저장 프로시저를 애플리케이션에서 절대 사용하지 말라!, 프로시져는 플랫폼(DB)에 종속적 데이터베이스 순수주의자 – 모든 단일 데이터베이스 상호작용은 저장 프로시저를 통해서만 수행되어야 한다. 리포팅을 위한 소수 테이블 조회 – iBATIS 매핑 다중 서브쿼리와 조인을 실행해서 수백만개의 레코드를 가져오는 복잡한 리포팅 – 저장 프로시저
40
iBATIS에서 XML사용하기 고급 쿼리 기법 XML파라미터 XML로 결과 생성하기
41
매핑 구문을 객체와 연관시키기 고급 쿼리 기법 복잡한 컬렉션(collection) 데이터베이스 I/O
“N+1 Select”문제 살펴보기 위 두 문제에 대한 해결책 적재 지연(lazy loading) N+1 Select 문제 피해가기 적재 지연 N+1 Select 해결 책 대용량의 데이터 셋이지만 한꺼번에 모두 필요하지는 않을 때 작은 데이터 셋이나 혹은 모든 데이터를 한꺼번에 사용해야 하는 데이터 셋 일 때 눈에 보이는 부분의 성능이 중요하고 부하 발생을 나중으로 미루고자 할 때 전반적인 성능 향상이 가장 중요할 때 [적재 지연과 N+1 Select 해결책 간의 차이점]
42
상속 고급 쿼리 기법 상속 매핑하기
43
잡다한 다른 활용법들 고급 쿼리 기법 Statement 타입과 DDL 사용하기 매우 큰 데이터 셋 처리하기
더 이상 질문을 회피하지 마세요 더 흥미로운 로우 핸들러의 또 다른 사용 예 [예제를 위한 엔티티 관계도]
44
트랜잭션은 무엇인가? 트랜잭션 간단한 은행 예제 트랜잭션의 특성 이해하기 원자성(Atomicity)
일관성(Consistency) 격리성(Isolation) 영속성(Durability)
45
자동 트랜잭션 트랜잭션
46
로컬 트랜잭션 트랜잭션 [로컬 트랜잭션의 영역]
47
글로벌 트랜잭션 트랜잭션 능동(active) 혹은 수동(passive) 트랜잭션 사용하기 트랜잭션을 시작하고 커밋하고 종료하기
[글로벌 트랜잭션 범위의 예] 능동(active) 혹은 수동(passive) 트랜잭션 사용하기 트랜잭션을 시작하고 커밋하고 종료하기 글로벌 트랜잭션이 필요한가?
48
트랜잭션 구분하기 트랜잭션 프리젠테이션 계층에서 트랜잭션 구분 짓기 퍼시스턴스 계층에서 트랜잭션 구분 짓기
[계층화된 아키텍처] 프리젠테이션 계층에서 트랜잭션 구분 짓기 퍼시스턴스 계층에서 트랜잭션 구분 짓기 비즈니스 로직 계층에서 트랜잭션 구분 짓기
49
동적인 WHERE 조건절 다루기 동적인 SQL 사용하기 [Category 테이블 다이어그램]
50
동적 요소들과 친숙해지기 동적인 SQL 사용하기 <dynamic> 요소 속성 내용 prepend (선택적)
open open값은 요소 내용에 접두사로 붙이기 위해 사용한다. open 값은 요소 내용이 공백일 때는 출력되지 않는다. open값은 prepend속성 값보다는 뒤에 붙는다. 예를 들면 prepend=“WHEN”이고 open=“(“라면 조합된 결과는 “WHEN (“ 가 될 것이다. close close값은 요소 내용의 뒤에 덧붙이기 위해 사용한다. 이 값은 요소 내용이 공백이라면 출력되지 않는다. [<dynamic> 요소 속성]
51
동적 요소들과 친숙해지기 동적인 SQL 사용하기 이항연산 요소 속성 내용 property (필수)
compareValue나 compareProperty와 비교하는데 사용할 파라미터 프로퍼티 prepend (선택적) 이 값은 보통 요소 내용의 가장 앞에 출력된다. 다음의 경우에는 prepend의 값이 출력되지 않고 무시된다 : (a)요소의 결과 내용이 공백인 경우, (b)요소가 처음으로 내용을 만들어 냈고 removeFirstPrepend 속성이 true인 요소에 내포되어 있는 경우, (c)<dynamic> 요소 다음에 공백이 아닌 내용을 처음으로 출력하고 prepend에 값이 지정되 있는 요소일 경우. open open값은 요소 내용에 접두사로 붙이기 위해 사용한다. open 값은 요소 내용이 공백일 때는 접두사로 붙지 않는다. open값은 prepend속성 값보다는 뒤에 붙는다. 예를 들면 prepend=“OR”이고 open=“(“라면 조합된 결과는 “OR (“ 가 될 것이다. close close값은 요소 내용의 뒤에 덧붙이기 위해 사용한다. 이 값은 요소 내용이 공백이라면 출력되지 않는다. removeFirstPrepend 이 값은 처음으로 내용을 출력하는 자식 요소의 prepend 속성 값을 출력할지 여부를 결정한다. compareProperty (compareValue가 명시되지 않았다면 필수) compareProperty는 property 속성에 의해 명명된 프로퍼티와 비교할 파라미터 객체의 프로퍼티를 명시한다. compareValue (compareProperty가 명시되지 않았다면 필수) property속성에 의해 명명된 프로퍼티와 비교할 정적인 비교값 [이항연산 요소 속성]
52
동적 요소들과 친숙해지기 동적인 SQL 사용하기 단항연산 요소 속성 내용 <isEqual>
property 속성값이 compareProperty값이나 compareValue 값과 같은지 검사 <isNotEqual> property 속성값이 compareProperty값이나 compareValue 값과 같지 않은지 검사 <isGreaterThan> property 속성값이 compareProperty값이나 compareValue 값보다 큰지 검사 <isGreaterEqual> property 속성값이 compareProperty값이나 compareValue 값보다 크거나 같은지 검사 <isLessThan> property 속성값이 compareProperty값이나 compareValue 값보다 작은지 검사 <isLessEqual> property 속성값이 compareProperty값이나 compareValue 값보다 작거나 같은지 검사 [iBATIS 이항연산 동적 요소] 단항연산 요소 속성 내용 property (필수) 상태비교를 위해 사용되는 변수명 prepend (선택적) 이 값은 보통 요소 내용의 가장 앞에 출력된다. 다음의 경우에는 prepend의 값이 출력되지 않고 무시된다 : (a)요소의 결과 내용이 공백인 경우, (b)요소가 처음으로 내용을 만들어 냈고 removeFirstPrepend 속성이 true인 요소에 내포되어 있는 경우, (c)<dynamic> 요소 다음에 공백이 아닌 내용을 처음으로 출력하고 prepend에 값이 지정되 있는 요소일 경우. open open값은 요소 내용에 접두사로 붙이기 위해 사용한다. open 값은 요소 내용이 공백일 때는 접두사로 붙지 않는다. open값은 prepend속성 값보다는 뒤에 붙는다. 예를 들면 prepend=“OR”이고 open=“(“라면 조합된 결과는 “OR (“ 가 될 것이다. close (선택적) close값은 요소 내용의 뒤에 덧붙이기 위해 사용한다. 이 값은 요소 내용이 공백이라면 출력되지 않는다. removeFirstPrepend (선택적) 이 값은 처음으로 내용을 출력하는 자식 요소의 prepend 속성 값을 출력할지 여부를 결정한다. [단항연산 요소 속성]
53
동적 요소들과 친숙해지기 동적인 SQL 사용하기 파라미터 요소 속성 내용 <isPropertyAvailable>
명시된 프로퍼티가 파라미터에 존재하는지 검사. 빈즈에서는 프로퍼티를 찾고 Map에서는 키를 찾는다. <isNotPropertyAvailable> 명시된 프로퍼티가 파라미터에 존재하지 않는지 검사. 빈즈에서는 프로퍼티를 찾고 Map에서는 키를 찾는다. <isNull> 명시된 프로퍼티가 null인지 검사. 빈즈에서는 프로퍼티를 찾고 Map에서는 키를 찾는다. 키가 존재하지 않으면 true를 반환한다. <isNotNull> 명시된 프로퍼티가 null이 아닌 다른값인지를 검사. 빈즈에서는 프로퍼티를 찾고 Map에서는 키를 찾는다. 키가 존재하지 않으면 false를 반환한다. <isEmpty> 명시된 프로퍼티가 null이거나 빈 문자열(“”), 빈 컬렉션이나 빈 String.valueOf()인지를 검사. <isNotEmpty> 명시된 프로퍼티가 null이 아니거나 빈 문자열(“”), 빈 컬렉션이나 빈 String.valueOf()가 아닌지를 검사. [단항연산 요소] 파라미터 요소 속성 내용 prepend (선택적) 이 값은 보통 요소 내용의 가장 앞에 출력된다. 다음의 경우에는 prepend의 값이 출력되지 않고 무시된다 : (a)요소의 결과 내용이 공백인 경우, (b)요소가 처음으로 내용을 만들어 냈고 removeFirstPrepend 속성이 true인 요소에 내포되어 있는 경우, (c)<dynamic> 요소 다음에 공백이 아닌 내용을 처음으로 출력하고 prepend에 값이 지정되 있는 요소일 경우. open open값은 요소 내용에 접두사로 붙이기 위해 사용한다. open 값은 요소 내용이 공백일 때는 접두사로 붙지 않는다. open값은 prepend속성 값보다는 뒤에 붙는다. 예를 들면 prepend=“OR”이고 open=“(“라면 조합된 결과는 “OR (“ 가 될 것이다. close (선택적) close값은 요소 내용의 뒤에 덧붙이기 위해 사용한다. 이 값은 요소 내용이 공백이라면 출력되지 않는다. removeFirstPrepend (선택적) 이 값은 처음으로 내용을 출력하는 자식 요소의 prepend 속성 값을 출력할지 여부를 결정한다. [파라미터 요소 속성]
54
동적 요소들과 친숙해지기 동적인 SQL 사용하기 <iterate>요소 속성 내용
<isParameterPresnt> 파라미터 객체가 존재하는지 평가 <isNotParameterPresent> 파라미터 객체가 존재하지 않는지 평가 [파라미터요소] <iterate>요소 속성 내용 property (필수) 리스트(컬렉션 혹은 배열)을 포함하고 있는 파라미터의 프로퍼티 prepend (선택적) 이 값은 보통 요소 내용의 가장 앞에 출력된다. 다음의 경우에는 prepend의 값이 출력되지 않고 무시된다 : (a)요소의 결과 내용이 공백인 경우, (b)요소가 처음으로 내용을 만들어 냈고 removeFirstPrepend 속성이 true인 요소에 내포되어 있는 경우, (c)<dynamic> 요소 다음에 공백이 아닌 내용을 처음으로 출력하고 prepend에 값이 지정되 있는 요소일 경우. open open값은 요소 내용에 접두사로 붙이기 위해 사용한다. open 값은 요소 내용이 공백일 때는 접두사로 붙지 않는다. open값은 prepend속성 값보다는 뒤에 붙는다. 예를 들면 prepend=“OR”이고 open=“(“라면 조합된 결과는 “OR (“ 가 될 것이다. close close값은 요소 내용의 뒤에 덧붙이기 위해 사용한다. 이 값은 요소 내용이 공백이라면 출력되지 않는다. conjunction(선택적) 이 속성의 값은 값 목록의 사이 사이에 출력되어 SQL 문장을 구성한다. removeFirstPrepend 이 값은 처음으로 내용을 출력하는 자식 요소의 prepend 속성 값을 출력할지 여부를 결정한다. [<iterate> 요소 속성]
55
모두 적용한 간단한 예제 동적인 SQL 사용하기 데이터를 가져오고 표시하는 방법을 정의하기
[JGameStore의 검색 결과 화면] 데이터를 가져오고 표시하는 방법을 정의하기
56
모두 적용한 간단한 예제 동적인 SQL 사용하기 데이터베이스 구조 결정하기 정적인 형태로 SQL 작성하기
[간단한 제품 쿼리에 사용할 테이블 다이어그램] 정적인 형태로 SQL 작성하기 동적인 SQL요소를 정적인 SQL에 적용하기
57
고급 동적 SQL 기법 동적인 SQL 사용하기 결과 데이터 정의하기 필수 입력 항목 정의하기 [검색 폼]
[제품 목록을 검색하는 데 사용할 다양한 테이블 간의 관계]
58
고급 동적 SQL 기법 동적인 SQL 사용하기 결과 데이터 정의하기 필수 입력 항목 정의하기 정적인 형태로 SQL 작성하기
[검색 폼] 필수 입력 항목 정의하기 정적인 형태로 SQL 작성하기 동적 SQL 요소를 정적 SQL에 적용하기
59
동적 SQL에 대안이 되는 접근법 동적인 SQL 사용하기 자바코드 사용하기 저장 프로시저 사용하기 iBATIS와 비교하기
60
동적 SQL의 미래 동적인 SQL 사용하기 간단해진 조건 요소 표현식(Expression Language)
61
간단한 iBATIS 캐싱 예제 캐시를 통한 성능 향상
62
iBATIS의 캐싱에 관한 철학 캐시를 통한 성능 향상
63
캐시 모델 이해하기 캐시를 통한 성능 향상 Type readOnly 속성 Serialize 속성 속성 내용 id (필수)
유일한 ID를 지정한다. 캐시 모델에 설정된 캐시를 사용하고자 하는 쿼리 매핑 구문에서 이 ID를 참조한다. type (필수) 이 값은 캐시 모델이 설정하는 캐시의 타입을 의미한다. 사용 가능한 값으로 MEMORY, LRU, FIFO, OSCACHE가 있다. 이 속성은 사용자 정의 CacheController 구현체의 완전한 클래스 이름 (Fully Qualified Class Name)으로 지정해도 된다. readOnly (선택적) 이 값을 true로 지정하면 캐시가 읽기 전용 캐시로 사용될 것임을 의미한다. 읽기 전용 캐시에서 가져온 객체는 객체의 프로퍼티들을 바꿀 수 없다. serialize (선택적) 이 속성은 캐시의 내용을 가져올 때 ‘깊은 복사’를 할지 여부를 지정한다. [<cacheModel>요소의 속성들] deep Copy : 객체의 모든 값을 복사하여 동일한 값을 가진 새로운 객체를 생성해서 전달하는 방식. 반대말로는 객체의 참조만 복사하는 얕은 복사 Shallow copy가 있다. Type 캐시 모델 타입 설명 MEMORY 이 모델은 단순하게 캐시된 데이터를 가비지 컬렉터가 삭제할 때까지 메모리에 저장한다. FIFO 이 모델은 고정된 크기의 모델로 ‘first in first out’ 알고리즘을 사용하여 메모리에서 캐시 항목들을 삭제한다. LRU 이 모델은 또 다른 고정된 크기의 모델로 ‘least recently used’ 알고리즘을 사용하여 메모리에서 캐시 항목들을 삭제한다. OSCACHE 이 모델은 OpenSymphony(혹은 OS) Cache를 사용한다. [내장 캐시 모델 타입들] readOnly 속성 Serialize 속성
64
캐시 모델 이해하기 캐시를 통한 성능 향상 readOnly와 serialize 조합 readOnly serialize 결과
이유 true false 좋음 캐시된 객체를 가장 빠르게 가져온다. 캐시된 객체의 공유 인스턴스를 반환하며, 잘못 사용하면 문제를 일으킬 수도 있다. 캐시된 객체를 빠르게 가져온다. 캐시된 객체를 깊은 복사 작업을 통해 가져온다. 주의요망! 캐시는 오직 호출하는 스레드의 세션이 살아 있는 동안에만 관련되고, 다른 스레드는 사용할 수는 없다. 나쁨 이 조합은 무의미한 설정이라는 점을 제외하고는 readOnly=false 그리고 serialize=true와 동일하게 작동한다. [readOnly와 serialize 속성의 조합에 대한 요약]
65
캐시 모델 내부의 요소사용하기 캐시를 통한 성능 향상 캐시 비우기(Cache flushing)
태그 목적 <flushOnExecute> 여기서 지정된 쿼리 매핑 구문이 실행되면 캐시의 내용을 지운다. <flushInterval> 캐시의 내용을 지우는 시간 간격을 정의한다. [readOnly와 serialize 속성의 조합에 대한 요약] <flushOnExecute> <flushInterval> 속성 의미 hour (선택사항) 캐시를 지우기까지 지나야 할 시간 minute (선택사항) 캐시를 지우기까지 지나야 할 분 seconds (선택사항) 캐시를 지우기까지 지나야 할 초 milliseconds (선택사항) 캐시를 지우기까지 지나야 할 밀리 초 [<flushInterval> 요소의 속성들] 캐시 모델 구현체의 프로퍼티 설정하기 속성 의미 name (필수사항) 설정할 프로퍼티의 이름 value (필수사항) 설정할 프로퍼티의 값 [<property> 요소의 속성들]
66
캐시 모델 타입 캐시를 통한 성능 향상 MEMORY LRU FIFO OSCACHE 스스로 만든 캐시 모델 타입 내용 WEAK
해당 참조 타입은 캐시된 객체를 빨리 비워버린다. 객체가 가비지 컬렉터에 의해 수거되는 것을 막지 않고 놔둔다. 가비지 컬렉터는 캐시된 객체를 처음 보자마자 삭제해 버릴 것이다. 단지 삭제되기 전의 객체에 접근하는 방법을 제공할 뿐이다. 이는 디폴트로 지정되는 참조 타입이다. 이 방식은 일관성 있게 객체에 접근하는 캐시를 사용 할 때 잘 작동한다. 캐시를 비우는 비율이 빠른 편이기 때문에 메모리 제한을 넘기지 못하도록 보장해준다. 이 방식을 사용하면 데이터베이스 히트 확률이 더 높아진다. SOFT SOFT 참조 타입도 중요한 메모리 용량 제한에 다달았을 때 객체를 삭제해도 되는 경우에 좋다. 메모리 용량이 허락하는 한 캐시된 객체를 계속 보관한다. 가비지 컬렉터는 더 많은 메모리가 필요하다고 판단되기 전까지는 이 객체들을 수거하지 않는다. 또한 메모리의 용량을 넘지 않을 것을 보장해 주고 WEAK 타입보다는 데이터베이스 히트 횟수가 적은 편이다. STRONG 이 타입은 메모리의 용량 한계가 얼마든지 간에 관계없이 캐시된 객체를 계속 보유하고 있다. 이 타입으로 저장된 객체는 지정된 비우기 시간 간격이 되기 전까지는 캐시에서 삭제되지 않는다. STRONG 타입의 캐시는 정적이고 작고 정기적으로 사용할 객체를 저장할 때 사용하도록 한다. 이 참조 차입은 데이터베이스 히트를 줄여서 성능을 향상시켜준다. 하지만 캐시의 용량이 지나치게 커져서 메모리 부족 오류를 발생시킬 수 있는 위험성을 안고 있다. [MEMORY 캐시 참조 타입] LRU FIFO OSCACHE 스스로 만든 캐시 모델
67
캐싱 전략 수립하기 캐시를 통한 성능 향상 읽기전용, 장기간 유지 데이터 캐싱 읽기/쓰기 가능한 데이터 캐싱
낡게 되는 (aging) 정적 데이터 캐싱하기
68
상세한 구현 숨기기 iBATIS 데이터 접근 객체(DAO) [간단하게 만든 DAO] 왜 분리하는가?
69
상세한 구현 숨기기 iBATIS 데이터 접근 객체(DAO) 간단한 예제 dao.xml 설정파일 DaoManager 생성하기
70
DAO 설정하기 iBATIS 데이터 접근 객체(DAO) <properties> 요소
<context> 요소 <transactionManager> 요소 타입별칭 트랜잭션 관리자/프로퍼티 설명 EXTERNAL ExternalDaoTransactionManager iBATIS DAO 프레임워크 외부에서 개발자가 자체적으로 트랜잭션을 관리하도록 하는 “아무것도 하지 않는” 트랜잭션 HIBERNATE HibernateDaoTransactionManager 하이버네이트의 트랜잭션 관리 기능에 위임 JDBC JdbcDaoTransactionManager - DataSource - JDBC.Driver - JDBC.ConnectionURL - JDBC.Username - JDBC.Password - JDBC.DefaultAutoCommit DataSource API를 통해 커넥션 풀링을 처리하고자 할 때 JDBC 타입을 사용한다. SIMPLE, DBCP 그리고 JNDI 이렇게 세 개의 DataSource 구현체가 지원된다. SIMPLE은 iBATIS의 SimpleDataSource의 구현체로 부하와 의존성이 가장 적은 독립적인 구현체이다. DBCP는 Jakarta DBCP DataSource를 사용하는 구현체이다. 마지막으로, JNDI는 DataSource 참조를 JNDI 디렉토리에서 가져오는 구현체이다. 이는 가장 일반적이고 유연한 설정 방식이다. DataSource 설정을 애플리케이션 서버에서 중앙 집중적으로 해줄 수 있기 때문이다. JTA JtaDaoTransactionManager - DBJndiContext - UserTransaction Java Transaction Architecture (JTA) API를 사용하여 트랜잭션을 관리한다. DataSource 구현체를 JNDI를 통해 가져오고 또한 UserTransaction 인스턴스도 JNDI를 통해 접근 가능해야 한다. OJB OjbBrokerTransactionManager OJB 트랜잭션 관리 기능으로 위임 SQLMAP SqlMapDapTransactionManager SQL Maps 트랜잭션 관리 기능으로 위임 TOPLINK ToplinkDaoTransactionManager TopLink 트랜잭션 관리 기능으로 위임 [iBATIS DAO 프레임워크에서 기본 제공하는 트랜잭션 관리자]
71
DAO 설정하기 iBATIS 데이터 접근 객체(DAO) EXTERNAL 트랜잭션 관리자 HIBERNATE 트랜잭션 관리자
JDBC 트랜잭션 관리자 SIMPLE 데이터 소스 DBCP 데이터 소스 JNDI 데이터 소스 JTA 트랜잭션 관리자 OJB 트랜잭션 관리자 SQLMAP 트랜잭션 관리자 TOPLINK 트랜잭션 관리자 자체적으로 생성한 트랜잭션 관리자나 다른 트랜잭션 관리자를 사용하기 DAO 요소
72
설정 팁들 iBATIS 데이터 접근 객체(DAO) 다중 서버 다중 데이터베이스의 방언(dialect) 실행시에 설정 변경하기
73
SQL Maps DAO 구현체 예제 iBATIS 데이터 접근 객체(DAO) iBATIS 를 사용하는 DAO설정
DaoManager 인스턴스 생성하기 트랜잭션 관리자 설정하기 맵 읽어들이기 DAO 구현체 코딩하기
74
플러그인 가능한 컴포넌트 설계 이해하기 iBATIS 확장하기 [플러그인 가능한 설계의 예] 확장 가능한 기능 확장 개요
TypeHandlerCallback 비표준 데이터베이스, 드라이버 그리고/또는 데이터 타입을 다루기 위한 사용자 정의 처리 로직을 구현한다. CacheController 개발자가 만든 캐시 코드 또는 써드파티 캐싱 솔루션을 지원하기 위한 사용자 정의 CacheController를 구현한다. DataSourceFactory 모든 표준적인 JDBC DataSource 구현체를 대체한다. TransactionConfig 사용자의 환경에서 가장 잘 작동하는 사용자 정의 트랜잭션 관리자를 구현한다. [계층화된 확장 요약]
75
사용자 정의 타입 핸들러로 작업하기 iBATIS 확장하기 사용자 정의타입 핸들러 구현하기
TypeHandlerCallback 생성하기 파라미터 설정하기 결과 가져오기 null 다루기 – valueOf()메소드는 왜 존재할까? TypeHandlerCallback을 등록해서 사용하기
76
CacheController 다루기 iBATIS 확장하기 CacheController 생성하기
클래스 상세 설명 LruCacheController Least Recently Used(LRU) 캐시는 캐시된 항목들을 언제 마지막으로 접근했는지를 기준으로 감시한다. 새로운 항목을 캐싱하기 위해 공간이 필요하면 최근에 가장 오랫동안 사용하지 않은 캐시 항목을 삭제한다. FifoCacheController First-In, First-Out(FIFO) 캐시는 캐시에서 가장 오래된 항목을 삭제해서 새로운 항목을 위한 공간을 만든다. MemoryCacheController Memory 캐시는 자바 메모리 모델과 가비지 컬렉터를 사용하여 캐시된 항목을 삭제할지 여부를 결정한다. OSCacheController OpenSymphony 캐시를 통해 OSCache라는 매우 고급 써드파티 캐싱 솔루션을 사용할 수 있다. OSCache는 그 자체에서 다양한 캐시 모델을 제공해 주며 분산 캐싱 같은 고급 기능들도 제공한다. [캐시 구현체 요약] CacheController 생성하기 CacheController의 저장, 가져오기, 삭제하기 CacheController를 등록해서 사용하기
77
지원되지 않는 DataSource 설정하기
iBATIS 확장하기
78
사용자 정의 트랜잭션 관리 iBATIS 확장하기 TransactionConfig 인터페이스 이해하기
구현체 설명 JdbcTransactionConfig JDBC Connection API가 제공하는 트랜잭션 기능을 사용 JtaTransactionConfig 전역 트랜잭션을 시작하거나 이미 존재하는 것에 합류 ExternalTransactionConfig 커밋과 롤백을 수행하지 않는 구현체, 다른 외부 트랜잭션 관리자가 커밋과 롤백을 하도록 한다. [캐시 구현체 요약] TransactionConfig 인터페이스 이해하기 Transaction 인터페이스 이해하기
79
iBATIS에서 단위 테스트하기 iBATIS 최적 활용 기법 매핑 계층 단위 테스트 테스트용 데이터베이스 인스턴스
[퍼시스턴스에 직접적으로 관련된 전형적인 계층들을 보여준다(퍼시스턴스와 관련 없는 계층은 이 그림에 없다)] 매핑 계층 단위 테스트 테스트용 데이터베이스 인스턴스 데이터베이스 스크립트 iBATIS 설정파일(SqlMapConfig.xml) iBATIS SqlMapClient 단위 테스트 데이터 접근 객체 (DAO) 단위 테스트하기 모의 객체로 DAO 단위 테스트하기 DAO 소비자 계층 단위 테스트 하기
80
iBATIS 설정 파일 관리하기 iBATIS 최적 활용 기법 클래스패스 안에 두기 파일들을 함께 두자 리턴타입 별로 정리하라
81
명명 규칙 iBATIS 최적 활용 기법 매핑 구문의 이름 짓기 파라미터 맵의 이름 짓기 결과 맵 이름 짓기 XML 파일들
주 설정 파일 SQL 매핑 파일
82
빈즈, MAP 혹은 XML? iBATIS 최적 활용 기법 자바빈즈 MAP XML 원시 타입(Primitives)
Similar presentations