When utilizing the iBATIS framework you define your SQL Maps to perform the basic CRUD functionality and additional business logic for an individual item. Very often you will be only updating single objects at a time and this is great, but what happens on those occasions where you find yourself processing hundreds of objects at the same time. The simple answer Batch Processing.

Batch Processing is the execution of a set of SQL statements without any user intervention. In essence it takes a group of commands executes them one at a time and then returns the updated count. Well in most cases some drivers won’t return the actual update count and instead returns 0.

Below is a short tutorial on how to perform Batch Processing in Java utilizing the Spring and iBATIS frameworks. In the example we will define and implement the method processInBatch method that will handle the processing. It assumes you have basic knowledge of each of the frameworks and focuses strictly on how to setup batch processing.

Initial Setup

Lets start by assuming for this example that we have a table in our database called APPLICATION and have defined the following basic SQL MAP which has been shortened for brevity.

<?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="Application">
 
	<!-- applicationMap - Application Object Map  -->
	<resultMap id="applicationMap" class="com.example.model.Application" groupBy="id">
		<result property="appId" column="APP_ID" />
		<result property="name" column="NAME" />
		...
	</resultMap>
 
	<!-- list -->
	<select id="Application.list" resultMap="applicationMap" >
		...
	</select>
 
	<!-- insert -->
	<insert id="Application.insert" parameterClass="com.example.model.Application">
		...
	</insert>
 
	<!-- update -->
	<update id="Application.update" parameterClass="com.example.model.Application">
		...
	</update>
 
	<!-- delete -->
	<delete id="Application.delete" parameterClass="com.example.model.Application">
		...
	</delete>
 
</sqlMap>

In addition to created the SQLMap we’ve also create our basic DAO interface ApplicationDAO and implementation ApplicationDAOImpl which extends Spring’s SqlMapClientDaoSupport class.

package com.example.dao;
 
import java.util.List;
import com.example.model.Application;
 
public interface ApplicationDAO {
 
	List<Application> list();
 
	int update( Application obj );
 
	Integer insert( Application obj );
 
	int delete( Application obj );
 
}
package com.example.dao.impl;
 
import java.util.List;
import org.springframework.orm.ibatis.support.SqlMapClientDaoSupport;
 
import com.example.dao.ApplicationDAO;
import com.example.model.Application;
 
public class ApplicationDAOImpl extends SqlMapClientDaoSupport implements ApplicationDAO {
 
	@SuppressWarnings("unchecked")
	public List<Application> list(){
		return (List<Application>) getSqlMapClientTemplate().queryForList( "Application.list" );
	}
 
	public Integer insert( Application obj ){
		Integer result = Integer.valueOf(-1);
		try {
			result = (Integer) getSqlMapClientTemplate().insert( "Application.insert", obj );
		} catch ( Exception e ) {
			log.error( "Failed to insert Application: " + e.getMessage() );
		}
		return result;
	}
 
	public int update( Application obj ){
		return getSqlMapClientTemplate().update( "Application.update", obj );
	}	
 
	public int delete( Application obj ){
		return getSqlMapClientTemplate().delete( "Application.delete", obj );
	}
 
}

Define the new processInBatch method

The processInBatch method will be responsible for setting up and executing the batch. It will take a list of Applications that are to be updated and perform the update SQL Map operation for each of them. To begin lets define the method stub in the ApplicationDAO interface and ApplicationDAOImpl class

// ApplicationDAO
int processInBatch( List<Application> applications );
// ApplicationDAOImpl
public int processInBatch( List<Application> applications ) {
 
}

Understanding the Batch Logic

To perform Batch Processing it is important to understand the two main classes that you will be interacting with SqlMapClientCallback and SqlMapExecutor

The SqlMapClientCallback class

The SqlMapClientCallback is a class to be overwritten in line that will perform the actual batch process. In it you define the doInSqlMapClient method. The SqlMapClientCallback object creates and passes the SqlMapExecutor instance to this method for your usage in setting up and executing the batch. The doInSqlMapClient method like the rest of the methods returns an Object so you can return any object you want.

try {
    Integer updateCount = (Integer) getSqlMapClientTemplate().execute( new SqlMapClientCallback() {
        public Object doInSqlMapClient( SqlMapExecutor executor ) throws SQLException {
 
        }
    });
    return updateCount.intVal();
catch (Exception e ) {
    return -1;
}

Looking at the above base implementation you can see that the general setup is the same for any batch processing you will need to perform the only difference is how you define the doInSqlMapClient method.

Implementing the doInSqlMapClient

The main batch worker is the SqlMapExecutor object. This object has 2 additional methods in addition to the basic insert, update, and execute: startBatch and executeBatch. The startBatch method is used to specify that you are performing the following statements as a batch, instead of executing them in line. Once you have set all your statements the executeBatch method is used to execute all of the statements in a batch and return the update count.

In our example as we are updating all the Applications passed to the processInBatch method we will start the batch, iterate over all applications, for each application call update on the executor for that object, then execute the batch.

executor.startBatch();
Iterator<Application> iter = applications.iterator();
while( iter.hasNext() ) {
    executor.update( "Application.update", iter.next() );
}
return new Integer( executor.executeBatch() );

The complete processInBatch method

public int processInBatch( List<Application> applications ) {
    try {
        Integer updateCount = (Integer) getSqlMapClientTemplate().execute( new SqlMapClientCallback() {
            public Object doInSqlMapClient( SqlMapExecutor executor ) throws SQLException {
                executor.startBatch();
                Iterator<Application> iter = applications.iterator();
                while( iter.hasNext() ) {
                    executor.update( "Application.update", iter.next() );
                }
                return new Integer( executor.executeBatch() );	
            }
        });
        return updateCount.intVal();
    catch (Exception e ) {
        return -1;
    }
}

Wrapping it all Up

There you have it we’ve created a method that executes multiple SQL statements as a batch. This reduces the overhead of performing multiple statements individually and can increase the performance of your applications especially as you get to large sets of statements. The greatest thing is that you don’t need to define any new sql statements and can use the ones you’ve already defined for doing single modifications.

, , , , , , , , ,

When writing applications, libraries, or other source code we often want some control over how it is used by the community. Licenses allow us developers to protect our rights to the source code while defining the terms in which others may utilize it. Two of the most common licenses used in open source software are the MIT License and GPL License. Although similar in that the they both allow users to utilize, modify, and redistribute the code there is one main difference between these licenses.  That difference is that the MIT License is permissive and the GPL License has strong copyleft.

Although it may be confusing at first which library you utilize comes down to whether or not you want to allow the use of your code in proprietary software.  The MIT License gives this permission under the stipulation that the License is distributed with that software, while the GPL License only grants use and modification by non-proprietary software.

As the copyright holder of the software you may decide you want to Dual License the software with both licenses allowing users to incorporate your source code into their own software under which ever license they want to use. This is also a viable option and is used by such libraries as JQuery.

Resources:

, , , , , ,

Why should developers use logging?

Logging to those new in the development world is the process of putting output statements inside your code to facilitate debugging and analysis of performance or issues.  Development of an application is completed by going through a life-cycle that typically includes requirements, code production, testing, and deployment in some manor. Logging enables developers to easily debug their code while in the testing phase by readily seeing output of variables and trace statements placed in their code, also while in the deployment phase having logging set up can enable the developer to analyze where an error occurred if the application crashes or gets hung up.

Be warned though that logging can slow down an application if used excessively. Be sure to use as needed during development but in production only have logging enabled for critical sections of the code.

What is log4j?

Log4j is a popular logging package for the java language licensed under the Apache Software License. It enables a developer to easily add logging to their applications that is easily configurable on run-time to restrict which statements are to be logged, how they are formatted, and where they should be logged. For those who program in the C family of languages log4j has been ported to C, C++, C#, and other languages.

How do I use log4j?

To utilize log4j in your application you need to have the log4j jar file in the project library and have the main Logger class imported by the statement:

import org.apache.log4j.Logger

Once the Logger is imported you can instantiate it for a Class by using the getLogger method, I suggest creating a static logger property for your class you want to do logging in. The getLogger method takes a string parameter to define the logger instance it is common practice to use the Classes class as the value.

private static Logger log = Logger.getLogger( ClassName.class );

To log a statement you simply use the trace, debug, info, warn, error, and fatal methods. These will log the inputted string at the level that matches the method.

log.info( "my first log statement" );

At this point your logging statements are all set to go but you have not as yet defined where they should be outputted. For beginners it is best to use the BasicConfigurator to configure the Logger to ouput to the console. This is great for development purposes and as you get more advanced you can move on to Property and DOM Configurators that enable more advanced configurations. It is important to remember that the configuration only needs to be run once per application and should be done before any logging statements.

import org.apache.log4j.BasicConfigurator;
BasicConfigurator.configure()

Resources

, ,

What is Test-driven Development?

Test-driven development is a process or technique for the development of software or code. The main focus with this process is the understanding of the requirements to enable the developer to write tests for new functionality and features before they write any code. This enables the developer to have a specific goal to work towards.

The development process contains 5 basic steps:

  1. Write a Test Case that will test a new feature or functionality.
  2. Run the Test Case
    1. The Test passes – Then either the new feature already exists in the code or the test does not test the requirement, return to Step 1
    2. The Test fails for unexpected reason – verify the Test is correct as it may not be written to properly test the feature, return to Step 1
    3. The Test fails as expected – proceed to step 3
  3. Write code
  4. Run the Test Case
    1. The Test fails – modify the code as it does not provide the necessary functionality, return to step 3
    2. The Test passes – new functionality added, proceed to step 5
  5. Refactor the code.  In this step the developer cleans up the code by removing magic numbers doing performance enhancements. By rerunning the Test Cases the developer can be assured that no bugs were introduced into the code.

This short 5 step life cycle enables the quick development of new features and functionality to an application. It also allows for regression testing of the software as new features are introduced ensuring that old functionality is not broken by any new enhancements.

What are some benefits to Test-driven Development?

Like all techniques the end results are dependent on the developer but some of the benefits that can be obtained by using this process are:

  • The quick development of new features as developers write code to add one feature at a time.
  • Enhanced confidence in the end product as in theory there is a Test Case for every functionality.
  • Backwards compatibility – by having a test suite for all functionality previous functionality will still be working correctly unless their Test Cases fail
  • Quick Roll Back capability – by tracking the code when each new feature is functional it allow the developer to quickly roll back to a previous state if the current code they are writing is failing to pass the Test Case.
  • Enhanced Developer confidence in themselves as the Test Cases give instant gratification that what they are writing works.
,