Saturday, February 8, 2014

How to enable lazy loading in iBatis

Lazy loading is conceptually a tactic of delaying the creation of an object until required. It is also referred as design pattern also. When we talk about lazy loading while fetching information from database, lazy loading essentially means to delay the execution of certain select/ sub-select queries till the time their related data is asked for.
In this tutorial, I am showing an example of lazy loading when developing your application with iBatis. There are following sections in this tutorial.
1) Create a maven project
2) Update runtime dependencies
3) Configure sql-map and config files with lazy loading enabled
4) Write domain classes
5) Test the application

1) Create a maven project

Run following commands to make a simple java project which is supported by eclipse plugin.
?
1
2
mvn archetype:generate -DgroupId=com.howtodoinjava.ibatis.demo -DartifactId=ibatisHelloWorld
-DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false

2) Update runtime dependencies

This will be done in pom.xml file. You can download the required jar files and put in lib folder as well.
pom.xml
?
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
<dependencies>
    
    <dependency>
        <groupId>org.apache.ibatis</groupId>
        <artifactId>ibatis-sqlmap</artifactId>
        <version>2.3.4.726</version>
    </dependency>
    
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.9</version>
    </dependency>
    
    <dependency>
        <groupId>cglib</groupId>
        <artifactId>cglib</artifactId>
        <version>2.2.2</version>
    </dependency>
    
    <dependency>
        <groupId>asm</groupId>
        <artifactId>asm-util</artifactId>
        <version>3.3.1</version>
    </dependency>
    
    <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>

3) Write domain classes

Below the domain classes UserTEO.java and DepartmentTEO.java. UserTEO has reference of DepartmentTEO which we are targeting to lazy load.
UserTEO.java
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package com.howtodoinjava.ibatis.demo.dto;
 
import java.io.Serializable;
 
public class UserTEO implements Serializable
{
    private static final long serialVersionUID = 1L;
     
    private Integer id;
    private String name;
    private String email;
    private String password;
    private int status;
    private DepartmentTEO department;
     
    //Getters and Setters
}
DepartmentTEO.java
?
1
2
3
4
5
6
7
8
9
10
11
12
13
package com.howtodoinjava.ibatis.demo.dto;
 
import java.io.Serializable;
 
public class DepartmentTEO implements Serializable
{
    private static final long serialVersionUID = 1L;
     
    private int id;
    private String name;
     
    //Getters and Setters
}

4) Configure sql-map and config files with lazy loading enabled

To configure iBatis in your application, you will need to configure sql-map-config.xml file and well as sql-map file also.
Below are two such files written for this tutorial.
sql-maps-config.xml
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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="false" lazyLoadingEnabled="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>
user.xml
?
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
xml version="1.0" encoding="UTF-8"?>
<sqlMap namespace="user">
 
    <typeAlias alias="USER" type="com.howtodoinjava.ibatis.demo.dto.UserTEO" />
    <typeAlias alias="DEPARTMENT" type="com.howtodoinjava.ibatis.demo.dto.DepartmentTEO" />
     
    <resultMap id="userResultMap" class="USER">
        <result property="id" column="ID" />
        <result property="name" column="NAME" />
        <result property="email" column="EMAIL" />
        <result property="password" column="PASSWORD" />
        <result property="status" column="STATUS" />
        <result property="department" column="DEPT_ID" select="user.getDepartmentById" />
    </resultMap>
     
    <resultMap id="departmentResultMap" class="DEPARTMENT">
        <result property="id" column="ID" />
        <result property="name" column="NAME" />
    </resultMap>
     
    <select id="getDepartmentById" parameterClass="java.lang.Integer" resultMap="departmentResultMap">
          SELECT * FROM DEPARTMENT WHERE ID = #value#
    </select>
     
    <select id="getUserById" parameterClass="java.lang.Integer" resultMap="userResultMap">
          SELECT * FROM USERINFO WHERE ID = #value#
    </select>
     
</sqlMap>

5) Test the application

I have written below code which loads the iBatis configuration, connects to DB and load user object. It first makes a call to user detail, the user object is loaded from database.
But Department data is selected only when I try to get it from user object. It means Department data is lazy loaded .
?
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
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 = manager.getUserById(1, sqlmapClient);
        System.out.println(user.getEmail());
         
        System.out.println("LAZY load the department");
         
        System.out.println(user.getDepartment().getName());
    }
}
Below is the output of program.
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
DEBUG [main] - Created connection 27994366.
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, DEPT_ID]
DEBUG [main] - {rset-100002} Result: [1, Demo User, demo-user@howtodoinjava.com, password, 1, 1]
DEBUG [main] - Returned connection 27994366 to pool.
demo-user@howtodoinjava.com
LAZY load the department
DEBUG [main] - Checked out connection 27994366 from pool.
DEBUG [main] - {conn-100003} Connection
DEBUG [main] - {conn-100003} Preparing Statement:      SELECT * FROM DEPARTMENT WHERE ID = ? 
DEBUG [main] - {pstm-100004} Executing Statement:      SELECT * FROM DEPARTMENT WHERE ID = ? 
DEBUG [main] - {pstm-100004} Parameters: [1]
DEBUG [main] - {pstm-100004} Types: [java.lang.Integer]
DEBUG [main] - {rset-100005} ResultSet
DEBUG [main] - {rset-100005} Header: [ID, NAME]
DEBUG [main] - {rset-100005} Result: [1, Finance]
DEBUG [main] - Returned connection 27994366 to pool.
Finance
source download
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