iBatis – Enable Lazy Loading Example

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.

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

<dependencies>
	<!-- iBatis support -->
    <dependency>
		<groupId>org.apache.ibatis</groupId>
		<artifactId>ibatis-sqlmap</artifactId>
		<version>2.3.4.726</version>
	</dependency>
	<!-- Database connectivity support -->
	<dependency>
	    <groupId>mysql</groupId>
	    <artifactId>mysql-connector-java</artifactId>
	    <version>5.1.9</version>
	</dependency>
	<!-- Proxy support (Mandatory) -->
	<dependency>
		<groupId>cglib</groupId>
		<artifactId>cglib</artifactId>
		<version>2.2.2</version>
	</dependency>
	<!-- Internal dependency (Required) -->
	<dependency>
		<groupId>asm</groupId>
		<artifactId>asm-util</artifactId>
		<version>3.3.1</version>
	</dependency>
	<!-- Internal dependency (Required) -->
	<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>

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

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

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

<?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>
    
	<!--  Lazy loading is globally enabled here -->
    <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

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

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.

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 !!

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.

3 thoughts on “iBatis – Enable Lazy Loading Example”

  1. Can you Please give the exapmple to call the Oracle stored procedure from the Ibatics that is returning the Cursor and mapped the result in the java Object

    Reply

Leave a Comment

HowToDoInJava

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