Saturday, February 8, 2014

How to enable caching in iBatis using OSCache

In previous post, we developed our first iBatis hello world application. Now lets make some additions to make it more advanced. I will start by adding caching capability.
Caching allows to retrieve data returned for specific query(s) 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.
Sections in this post:
Adding maven dependency
Update sql-map-config.xml
Update sql data mapping file
Test the code

Adding maven dependency

Update the pom.xml with following dependency for adding OSCache support to project.
?
1
2
3
4
5
6
7
8
9
10
11
12
13
<dependency>
    <groupId>opensymphony</groupId>
    <artifactId>oscache</artifactId>
    <version>2.4</version>
    <scope>compile</scope>
    
    <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 using :
mvn eclipse:eclipse

Update sql-map-config.xml

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:
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
xml version="1.0" encoding="UTF-8" ?>
        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>

Update sql data mapping file

To enable caching for sql queries, two things needs to be done:
A) Define cache model like this:
?
1
2
3
4
<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.
B) Add cache model to SQL statements
Add cacheModel=”cache-user” to all select statements for which you want to store result in cache.
?
1
2
3
<select id="getUserById" parameterClass="java.lang.Integer" resultMap="userResultMap" cacheModel="cache-user">
       SELECT * FROM USERINFO WHERE ID = #value#
</select>

Test the code

Lets test the code.
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
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());
    }
}
 
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 !!

4 comments:

oakleyses said...

louis vuitton handbags, oakley sunglasses, louboutin, longchamp outlet, nike shoes, louis vuitton outlet stores, chanel handbags, burberry outlet, prada outlet, jordan shoes, tiffany and co, michael kors outlet, tory burch outlet, louis vuitton outlet, longchamp handbags, nike free, true religion jeans, michael kors outlet, kate spade outlet, polo ralph lauren outlet, tiffany and co, prada handbags, polo ralph lauren outlet, michael kors outlet, michael kors outlet, longchamp handbags, oakley sunglasses, ray ban sunglasses, kate spade handbags, burberry outlet, louis vuitton outlet, louboutin outlet, louboutin, coach factory outlet, air max, air max, coach outlet, gucci outlet, christian louboutin shoes, michael kors outlet, coach purses, ray ban sunglasses, michael kors outlet, louis vuitton, coach outlet store online, true religion jeans, oakley sunglasses cheap

oakleyses said...

ralph lauren, lululemon, air max, hollister, north face, nike air max, polo lacoste, vanessa bruno, timberland, vans pas cher, louboutin, louis vuitton, oakley pas cher, air max pas cher, nike roshe run, air max, true religion outlet, barbour, sac longchamp, air force, hollister, sac louis vuitton, nike free, polo ralph lauren, nike trainers, louis vuitton uk, nike roshe, sac hermes, longchamp, michael kors, sac burberry, sac guess, mulberry, new balance pas cher, converse pas cher, sac louis vuitton, hogan outlet, nike tn, north face, true religion outlet, ray ban pas cher, michael kors, air jordan, nike blazer, nike free pas cher, michael kors pas cher, abercrombie and fitch, ray ban sunglasses

oakleyses said...

mac cosmetics, mont blanc, marc jacobs, canada goose outlet, nike huarache, vans shoes, soccer jerseys, hollister, giuseppe zanotti, beats by dre, abercrombie and fitch, longchamp, insanity workout, celine handbags, bottega veneta, ghd, nfl jerseys, north face outlet, chi flat iron, ugg boots, birkin bag, ugg australia, canada goose, herve leger, ugg pas cher, rolex watches, valentino shoes, canada goose uk, canada goose, ferragamo shoes, canada goose, ugg boots, uggs outlet, north face jackets, soccer shoes, asics running shoes, new balance shoes, p90x, lululemon outlet, canada goose jackets, mcm handbags, instyler, babyliss pro, ugg, wedding dresses, jimmy choo outlet, reebok outlet, nike roshe run

oakleyses said...

parajumpers, karen millen, air max, converse, pandora charms, moncler, louboutin, moncler, links of london, lancel, juicy couture outlet, oakley, hollister, pandora charms, supra shoes, thomas sabo, canada goose, gucci, wedding dresses, timberland boots, swarovski crystal, air max, coach outlet store online, moncler, ray ban, canada goose, moncler, ugg, louis vuitton, swarovski, hollister, montre homme, moncler, hollister clothing store, ralph lauren, rolex watches, moncler outlet, moncler, iphone 6 cases, baseball bats, juicy couture outlet, toms shoes, vans, pandora jewelry, ugg, converse shoes