iBatis Cache의 사용

1. iBatis Cache의 이해

1.1 CacheModel의 이해

  • iBatis는 <cacheModel>을 통해 캐시 기능을 제공한다.
  • 쿼리 결과를 cacheModel 매개 변수를 지정하여 간단하게 구현 할 수 있다.

Cache 적용 예


<cacheModel id="empCache" type="LRU" readOnly="true" serialize="false">
    <flushInterval minutes="60"/>
    <property name="cache-size" value="10" /> 
    <flushOnExecute statement="emp.insertEmp"/>
</cacheModel>

<select id="selectEmpList" resultClass="emp" cacheModel="cachemodel.empCache" >
SELECT empno, ename, job, sal
FROM  emp  
</select> 

CacheModel 속성
속성설 명
Id캐시 아이디
typeMEMORYGC가 발생하기 전까지 메모리에 저장한다.
FIFOFirst In First Out 캐시 알고리즘 사용
LRULeast Recently Used 캐시 알고리즘 사용
OSCACHEOSCache 사용
readOnlytrue캐시가 읽기 전용이 된다. 동시에 여러 쓰레드가 읽을 수 있다. (기본값)
false읽기 전용 아님
serializetrue/false직렬화 여부

1.2 CacheModel 하위 태그들

flushOnExecute
  • 캐시가 flush될 sqlMap id를 지정한다.
  • 위 예에서 emp.insertEmp 문장이 실행되면 캐시가 flush 된다.
flushInterval
  • 캐시가 flush 되는 시간을 지정한다.
property cache-size 속성
  • FIFO, LRU 사용시 캐시가 저장 될 개수 이다.

2. iBatis Cache 실습

2.1 Cache SQLMap XML 파일 작성

  • /src/main/resources/sqlmap/ 폴더에 CacheModel.xml 파일을 생성한다.
  • 아래와 같이 LRU 캐시를 생성하고, 사원정보 등록 및 삭제시 캐시 초기화 옵션을 적용한다.

/src/main/resources/sqlmap/CacheModel.xml


<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE sqlMap PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN" "http://ibatis.apache.org/dtd/sql-map-2.dtd">
 
<sqlMap namespace="cachemodel">
		
	<cacheModel id="empCache" type="LRU" readOnly="true" serialize="false">
	  	<flushInterval minutes="60"/>
	  	<property name="cache-size" value="10" /> 
	  	<flushOnExecute statement="emp.insertEmp"/>
	  	<flushOnExecute statement="emp.deleteEmp"/>
	</cacheModel>
     
</sqlMap>

2.2 사원목록 조회 캐시설정

  • Emp.xml 파일 사원목록조회("selectEmpList")에 cacheModel 속성을 이용해서 캐시설정을 한다.
    • cacheModel="cachemodel.empCache"

/src/main/resources/sqlmap/Emp.xml


<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE sqlMap PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN" "http://ibatis.apache.org/dtd/sql-map-2.dtd">

<sqlMap namespace="emp">

  	<typeAlias alias="emp" type="com.oracleclub.study.mvc.model.Emp"/>

 	<select id="selectEmpList" resultClass="emp"  cacheModel="cachemodel.empCache" >
		SELECT empno, ename, job, sal, NVL(mgr,0) mgr
		  FROM emp 
 	</select> 	

    <select id="selectEmp" resultClass="emp" parameterClass="int"  >
		SELECT empno, ename, job, sal, NVL(mgr,0) mgr, deptno
		  FROM emp 
		 WHERE empno = #empno#
 	</select> 
 	
	<insert id="insertEmp"  parameterClass="emp"  >
 	    INSERT INTO emp (empno, ename, job, sal, mgr,  hiredate, deptno)
        VALUES (#empno#, #ename#, #job#, #sal#, 0, #hiredate#, #deptno#)
    </insert> 
  	
</sqlMap>


2.3 sql-map-config.xml 파일 수정

  • sql-map-config.xml 파일에 아래와 같이 CacheModel.xml 설정을 추가한다.

/src/main/resources/datasource/sql-map-config.xml


<?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">

<sqlMapConfig>
	<settings
		cacheModelsEnabled="true"
		enhancementEnabled="true"
		lazyLoadingEnabled="true"		
		useStatementNamespaces="true"
	/>
	
	<sqlMap resource="sqlmap/CacheModel.xml" /> 
	<sqlMap resource="sqlmap/Emp.xml"/> 
	
</sqlMapConfig> 

2.4 테스트

  • 최초 조회시 아래와 같이 SQL문장이 실행되고 cache 정보를 저장하는지 확인한다.

 {pstm-100001} Executing Statement:    SELECT empno, ename, job, sal, NVL(mgr,0) mgr     FROM emp    
 {pstm-100001} Parameters: []
 {pstm-100001} Types: []
 {rset-100002} ResultSet
 {rset-100002} Header: [EMPNO, ENAME, JOB, SAL, MGR]
 {rset-100002} Result: [1111, tester, tester, 1111, 0]
 {rset-100002} Result: [7369, SMITH, CLERK, 800, 7902]

 Cache 'cachemodel.empCache': stored object 'Emp[empno=1111,mgr=0,sal=1111,deptno=0,ename=tester,job=tester,hiredate=<null>,filename=<null>],...'

 
  • 이후 조회시 SQL문을 실행하지 않고, cache를 이용해서 데이터를 조회하는지 확인한다.

Cache 'cachemodel.empCache': retrieved object 'Emp[empno=1111,mgr=0,sal=1111,deptno=0,ename=tester,job=tester,hiredate=<null>,filename=<null>],...'