iBatis OSCache example tutorial

After developing first iBatis hello world application, lets add caching capability using OSCache.

Caching allows to retrieve data returned for specific queries to be stored in temporary memory from where it can be fetched again for exactly same query (provided cache has not been refreshed from last fetch). If cache is refreshed, all queries will again go to database and store their data in cache.

iBatis can use multiple supported cache solution, and I am using here one of them i.e. OSCache.

Table of Contents

1. Maven dependency
2. Update sql-map-config.xml
3. Update sql data mapping file
4. Demo

1. OSCache maven dependency

Update the pom.xml with following dependency for adding OSCache support to project.

<dependency>
    <groupid>org.apache.ibatis</groupid>
    <artifactid>ibatis-sqlmap</artifactid>
    <version>2.3.4.726</version>
</dependency>

<dependency>
    <groupId>opensymphony</groupId>
    <artifactId>oscache</artifactId>
    <version>2.4</version>
    <scope>compile</scope>
    <!-- This excludes the transitive dependency on JMS -->
    <exclusions>
            <exclusion>
                    <groupId>javax.jms</groupId>
                    <artifactId>jms</artifactId>
            </exclusion>
    </exclusions>
</dependency>

OSCache is dependent on JMS also, which is not required for this demo… so exclude it. If you do not exclude it, you may find an error while updating the dependency.

2. Update sql-map-config.xml with cacheModelsEnabled=true

To add caching support, update the settings tag in sql-map-config.xml file with cacheModelsEnabled=”true”.

The updated config file will look like this:

<?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 useStatementNamespaces="true" cacheModelsEnabled="true"/>
    
    <transactionManager type="JDBC">
        <dataSource type="SIMPLE">
          <property name="JDBC.Driver" value="com.mysql.jdbc.Driver"/>
          <property name="JDBC.ConnectionURL"  value="jdbc:mysql://localhost:3306/demoDB"/>
          <property name="JDBC.Username" value="root"/>
          <property name="JDBC.Password" value="lg225295"/>
        </dataSource>
      </transactionManager>
    
    <sqlMap resource="user.xml"/>

</sqlMapConfig>

3. Update sql data mapping file

To enable caching for sql queries, two things needs to be done:

3.1. Define cacheModel element

<cacheModel id="cache-user" type="OSCACHE" readOnly="true">
        <flushInterval hours="24"></flushInterval>
        <property name="cache-size" value="50"></property>
</cacheModel>
  • id: Name of cache where all execution results will be stored for a query to which this model will be specified.
  • type: This attribute defines the cache model implementation used.
  • readOnly: This attribute defines that if cache will be used for reading only.
  • flushInterval: This tag defines the number of hours after which cache will be refreshed automatically.
  • cache-size: It defines that this cache will store maximum 50 statement’s results after which it will start deleting old cache and store new one.

3.2. Add cache model to SQL statements

Add cacheModel=”cache-user” to all select statements for which you want to store result in cache.

<select id="getUserById" parameterClass="java.lang.Integer" resultMap="userResultMap" cacheModel="cache-user">
       SELECT * FROM USERINFO WHERE ID = #value#
</select>

4. iBatis demo of OSCache cache

Lets test the code.

package com.howtodoinjava.ibatis.demo;

import java.io.Reader;

import com.howtodoinjava.ibatis.demo.dao.UserDao;
import com.howtodoinjava.ibatis.demo.dao.UserDaoIbatis;
import com.howtodoinjava.ibatis.demo.dto.UserTEO;
import com.ibatis.common.resources.Resources;
import com.ibatis.sqlmap.client.SqlMapClient;
import com.ibatis.sqlmap.client.SqlMapClientBuilder;

public class TestMain {
	public static void main(String[] args) throws Exception
	{
		UserDao manager = new UserDaoIbatis();

		Reader reader = Resources.getResourceAsReader("sql-maps-config.xml");
		SqlMapClient sqlmapClient = SqlMapClientBuilder.buildSqlMapClient (reader);

		/*UserTEO user = new UserTEO();
		user.setId(1);
		user.setName("Demo User");
		user.setPassword("password");
		user.setEmail("demo-user@howtodoinjava.com");
		user.setStatus(1);

		manager.addUser(user,sqlmapClient);
		*/
		UserTEO createdUser = manager.getUserById(1, sqlmapClient);
		System.out.println(createdUser.getEmail());

		createdUser = manager.getUserById(1, sqlmapClient);
		System.out.println(createdUser.getEmail());

		createdUser = manager.getUserById(1, sqlmapClient);
		System.out.println(createdUser.getEmail());

		createdUser = manager.getUserById(1, sqlmapClient);
		System.out.println(createdUser.getEmail());
	}
}

Program Output.

DEBUG [main] - Cache 'user.cache-user': cache miss
DEBUG [main] - Created connection 32604499.
DEBUG [main] - {conn-100000} Connection
DEBUG [main] - {conn-100000} Preparing Statement:      SELECT * FROM USERINFO WHERE ID = ?
DEBUG [main] - {pstm-100001} Executing Statement:      SELECT * FROM USERINFO WHERE ID = ?
DEBUG [main] - {pstm-100001} Parameters: [1]
DEBUG [main] - {pstm-100001} Types: [java.lang.Integer]
DEBUG [main] - {rset-100002} ResultSet
DEBUG [main] - {rset-100002} Header: [ID, NAME, EMAIL, PASSWORD, STATUS]
DEBUG [main] - {rset-100002} Result: [1, Demo User, demo-user@howtodoinjava.com, password, 1]
DEBUG [main] - Cache 'user.cache-user': stored object 'com.howtodoinjava.ibatis.demo.dto.UserTEO@13917ef'
DEBUG [main] - Returned connection 32604499 to pool.
demo-user@howtodoinjava.com
DEBUG [main] - Cache 'user.cache-user': retrieved object 'com.howtodoinjava.ibatis.demo.dto.UserTEO@13917ef'
demo-user@howtodoinjava.com
DEBUG [main] - Cache 'user.cache-user': retrieved object 'com.howtodoinjava.ibatis.demo.dto.UserTEO@13917ef'
demo-user@howtodoinjava.com
DEBUG [main] - Cache 'user.cache-user': retrieved object 'com.howtodoinjava.ibatis.demo.dto.UserTEO@13917ef'
demo-user@howtodoinjava.com

As you can see, first user object is fetched from database, but last 3 calls get the user object from cache and database if not touch again.

Happy Learning !!

Was this post helpful?

Join 7000+ Fellow Programmers

Subscribe to get new post notifications, industry updates, best practices, and much more. Directly into your inbox, for free.

1 thought on “iBatis OSCache example tutorial”

Leave a Comment

HowToDoInJava

A blog about Java and its related technologies, the best practices, algorithms, interview questions, scripting languages, and Python.