How to integrate Spring with iBatis?

1) Introduction

iBatis is an object-relational mapping tool (ORM) that simplifies access to database. This article details the steps needed for integrating Spring with iBatis. Through such an integration, objects that are specific to iBatis can utilise all the benefits given by Spring’s IOC Container. This is not an introductory article for both Spring and iBatis Frameworks. First-time readers are encouraged to read the Introductory article for Spring in javabeat Introduction to Spring Web Framework to know the preliminary concepts related to Spring.

If you are beginner for spring framework, please read our article on introduction to spring framework, spring aop, spring mvc and list of spring articles. You can find the list of recommended books for spring. Javabeat covers extensive articles on the spring framework. If you are interested in receiving the updates, please subscribe here.

2) Step-by-Step Procedure for Integration

2.1) Introduction

We are going to create a sample table in the MySql Database and going to access the data within it using Spring-iBatis Integration. The required bundles needed to build and run the sample program are listed below.

  • Spring Distribution
  • MySql Database
  • MySql Database Driver

2.2) Creating tables

Create a table called Jsr which contains relevant information for holding information like name, id, description and specification lead for a Java Specification Request (JSR). Issue the following command in the MySql Client command prompt to create the table,

create table Jsr (JsrId varchar(10), JsrName varchar(50), JsrDescription,  varchar(500), SpecLead varchar(100));

2.3) Creating the Java Equivalent

Now let us create a equivalent Java class for the Jsr table. This class, will contain properties that will map to the column names in the Jsr table. Given here is the complete code listing for the Jsr Java class,
Jsr.java

package javabeat.net.articles.spring.ibatis;

public class Jsr
{
    private String id;
    private String name;
    private String description;
    private String specLead;

    public String getId()
    {
        return id;
    }

    public void setId(String id)
    {
        this.id = id;
    }

    public String getName()
    {
        return name;
    }

    public void setName(String name)
    {
        this.name = name;
    }

    public String getDescription()
    {
        return description;
    }

    public void setDescription(String description)
    {
        this.description = description;
    }

    public String getSpecLead()
    {
        return specLead;
    }

    public void setSpecLead(String specLead)
    {
        this.specLead = specLead;
    }

    public String toString()
    {
        return 'Id = ' + id + ', Name = ' + name +
            ', Description = ' + description + ', Lead = ' + specLead;
    }
}

2.4) JsrDao Class

Then, we need to get into the client-facing Dao interface design. This is the interface that clients will be depending on, to perform various database operations like selection of rows, insertion, deletion, updating data etc.
JsrDao.java

package javabeat.net.articles.spring.ibatis;

import java.util.List;

public interface JsrDao
{

    public List selectAllJsrs();
    public Jsr selectJsrById(String jsrID);

    public void insertJsr(Jsr insertJsr);
    public void deleteJsr(String jsrId);
    public void updateJsr(Jsr jsrWithNewValues);

}

2.5) iBatis Mapping File

Jsr.xml

<?xml version='1.0' encoding='UTF-8' standalone='no'?>
<!DOCTYPE sqlMap PUBLIC '-//iBATIS.com//DTD SQL Map 2.0//EN'
'http://www.ibatis.com/dtd/sql-map-2.dtd'>

<sqlMap>

    <typeAlias type = 'javabeat.net.articles.spring.ibatis.Jsr' alias = 'jsr'/>

    <resultMap class = 'jsr' id = 'result'>
        <result property = 'id' column = 'JsrId'/>
        <result property = 'name' column = 'JsrName'/>
        <result property = 'description' column = 'JsrDescription'/>
        <result property = 'specLead' column = 'SpecLead'/>
    </resultMap>

    <select id = 'selectAllJsrs' resultMap = 'result'>
        select * from Jsr
    </select>

    <select id = 'selectJsrById' resultMap = 'result' parameterClass = 'string'>
        select * from Jsr where JsrId = #value#
    </select>

    <insert id = 'insertJsr' parameterClass='jsr'>
        insert into Jsr (JsrId, JsrName, JsrDescription, SpecLead) values (#id#, #name#, #description#, #specLead#)
    </insert>

    <delete id = 'deleteJsr' parameterClass='string'>
        delete from Jsr where JsrId = #value#
    </delete>

    <update id = 'updateJsr' parameterClass='jsr'>
        update Jsr set JsrName = #name#, JsrDescription = #description#, SpecLead = #specLead#
        where JsrId = #id#
    </update>

</sqlMap>

iBatis mapping file contains the mapping information between a Java class and its corresponding table in the database. Not only does it contain this mapping information, but also it contains many definitions for Named Queries. A Named Query is just a query defined with some name so that it can be reused across multiple modules.
The above Xml file starts with an element called 'typeAlias' which is just a short-name for 'javabeat.net.articles.spring.ibatis.Jsr'. Instead of referencing the fully-qualified name of the Jsr class, now it can be shortly referred as 'jsr' in the other sections of the Xml file. Next comes the mapping information specified in the form of 'resultMap' element where the associations between the Java properties for the corresponding column names are made.
Then, the Named Queries section follows. A query called 'selectAllJsrs' has been defined which is actually a select query. The query string value is manifested in the form of 'select * from Jsr'. By having such a query definition, it can be used elsewhere in the Application just by referring the query identifier. Now, let us choose a query definition that illustrates passing parameters to it. The query identifier 'selectJsrById' needs the JsrId as a parameter using which it can filter the number of rows fetched. This can be represented by using the attribute 'parameterClass'. Here 'string' stands for java.lang.String which means that the parameter is of type String. Similarly there are values like 'int', 'float', etc for java.lang.Integer and java.lang.Float respectively. Inside the query definition, we have the following query string,

select * from Jsr where JsrId = #value#

In the above query string, we have defined a new symbol called 'value'. This is the default symbol name for the parameter and since we have only one parameter it would not cause any problem. The expression '#value#' will be substituted with the values specified at the run-time. (Later we will see how the value gets substituted to the above expression).
Now, let us see a query definition that accepts multiple parameters. In the query definition 'insertJsr', we want the jsr id, jsr name, jsr description and spec lead values to get inserted and we have defined the query string as follows,

insert into Jsr (JsrId, JsrName, JsrDescription, SpecLead) values (
    #id#, #name#, #description#, #specLead#)

In the query definition, the value of the parameter value is pointing to ‘jsr’, which means that during run-time the query string will get translated as follows,

insert into Jsr (JsrId, JsrName, JsrDescription, SpecLead) values (
    jsr.getId(), jsr.getName(),jsr.getDescription(), jsr.getSpecLead())

2.6) iBatis Configuration File

The Configuration file for iBatis contains references to various mapping files as well as to the dataSource. But in our case, we would not define any dataSource related information in the Configuration file, but instead we will have it in the Spring Configuration file.
SqlMapConfig.xml

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE sqlMapConfig
PUBLIC '-//iBATIS.com//DTD SQL Map Config 2.0//EN'
'http://www.ibatis.com/dtd/sql-map-config-2.dtd'>

<sqlMapConfig>
<sqlMap resource='./spring/ibatis/Jsr.xml' />
</sqlMapConfig>

2.7) Implementation for JsrDao

We have designed only the client-facing interface in section 2.4. In this section, we shall see the implementation for the same. The following class extends SqlMapClientDaoSupport for getting reference to SqlMapClientTemplate object which simplifies the access to most of the database related operations.
JsrDaoImpl.java

package javabeat.net.articles.spring.ibatis;

import java.util.List;

import org.springframework.orm.ibatis.SqlMapClientTemplate;
import org.springframework.orm.ibatis.support.SqlMapClientDaoSupport;

public class JsrDaoImpl extends SqlMapClientDaoSupport implements JsrDao
{

    @Override
    public List selectAllJsrs()
    {
        SqlMapClientTemplate template = getSqlMapClientTemplate();
        return (List)template.queryForList('selectAllJsrs');
    }

    @Override
    public Jsr selectJsrById(String jsrID)
    {
        SqlMapClientTemplate template = getSqlMapClientTemplate();
        Object objectJsr = template.queryForObject('selectJsrById', jsrID);
        return objectJsr instanceof Jsr ? ((Jsr)objectJsr) : null;
    }

    @Override
    public void insertJsr(Jsr insertJsr)
    {
        SqlMapClientTemplate template = getSqlMapClientTemplate();
        template.insert('insertJsr', insertJsr);
    }

    @Override
    public void deleteJsr(String jsrId)
    {
        SqlMapClientTemplate template = getSqlMapClientTemplate();
        template.delete('deleteJsr', jsrId);
    }

    @Override
    public void updateJsr(Jsr jsrWithNewValues)
    {
        SqlMapClientTemplate template = getSqlMapClientTemplate();
        template.update('updateJsr', jsrWithNewValues);
    }
}

All the CRUD operations like select(), delete(), insert(), update() will take the named query object which was previously defined in the Configuration file.

2.8) Spring Configuration File

The Spring configuration that we are going to see has 3 sections. The first section configures a Spring Bean for database access like the data source, the driver class name and username/password information etc. Next we have defined a Factory Bean for reading all the mapping definitions and the named query information in the iBatis Configuration file. This Bean is the 'SqlMapClientFactoryBean' and it references the configuration file 'SqlMapConfig.xml'. The final section is the definition of the JsrDaoImpl bean for client access and it contains references to both the data-source and the sqlMapClientFactoryBean that were declared previously.
spring-ibatis.xml

<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE beans PUBLIC '-//SPRING//DTD BEAN//EN'
'http://www.springframework.org/dtd/spring-beans.dtd'>

    <beans>

        <bean id='dataSource'

        destroy-method='close'>
            <property name='driverClassName'>
                <value>com.mysql.jdbc.Driver</value>
            </property>
            <property name='url'>
                <value>jdbc:mysql://localhost/test</value></property>
            <property name='username'><value>root</value></property>
            <property name='password'><value>rootPassword</value></property>
    </bean>

    <bean id='sqlMapClient'   >
        <property name='configLocation'>
            <value>./spring/ibatis/SqlMapConfig.xml</value>
        </property>
    </bean>

    <bean id='jsrDao'   >
        <property name='dataSource'><ref local='dataSource'/></property>
        <property name='sqlMapClient'><ref local='sqlMapClient'/></property>
    </bean>

</beans>

2.9) Client Application

JsrClientApplication.java

package javabeat.net.articles.spring.ibatis;

import java.util.List;

import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;

public class JsrClientApplication
{

    public static void main(String[] args)
    {

        Resource resource = new FileSystemResource(
            './src/spring/ibatis/spring-ibatis.xml');
        BeanFactory beanFactory = new XmlBeanFactory(resource);

        JsrDaoImpl jsrDao = (JsrDaoImpl)beanFactory.getBean('jsrDao');

        System.out.println('Inserting JSR's');
        insertJsrs(jsrDao);

        System.out.println('Listing all JSR's');
        List allJsrs = jsrDao.selectAllJsrs();
        for (Jsr aJsr : allJsrs)
        {
            System.out.println(aJsr);
        }

        System.out.println('Selecting a JSR by Id 'JSR002'');
        Jsr aJsr = jsrDao.selectJsrById('JSR002');
        System.out.println(aJsr);

        System.out.println('Updating a JSR');
        Jsr fourthJsr = allJsrs.get(3);
        fourthJsr.setName('Servlets-Updated');
        fourthJsr.setDescription('Java Servlets and JSP-Updated');
        fourthJsr.setSpecLead('Belkin-Updated');
        jsrDao.updateJsr(fourthJsr);

        System.out.println('Deleting a JSR');
        jsrDao.deleteJsr('JSR004');
    }

    static void insertJsrs(JsrDaoImpl jsrDao)
    {
        Jsr newJsr = createJsr('JSR001', 'JMX',
            'Java Management Extension', 'McManus');
        jsrDao.insertJsr(newJsr);

        newJsr = createJsr('JSR002', 'XML',
            'XML Parsing Spec', 'Rajiv');
        jsrDao.insertJsr(newJsr);

        newJsr = createJsr('JSR003', 'JDO',
            'Java Data Objects', 'Russell');
        jsrDao.insertJsr(newJsr);

        newJsr = createJsr('JSR004', 'Servlets',
            'Java Servlets and JSP', 'Belkin');
        jsrDao.insertJsr(newJsr);
    }

    static Jsr createJsr(String id, String name, String description, String specLead)
    {
        Jsr newJsr = new Jsr();
        newJsr.setId(id);
        newJsr.setName(name);
        newJsr.setDescription(description);
        newJsr.setSpecLead(specLead);
        return newJsr;
    }
}

The Client Application in the above case gets a reference to the JsrDao object defined in the Spring Configuration file and makes use of it by testing the various available CRUD operations.

3) Conclusion

This article provided the various introductory details for integrating iBatis with Spring Framework. The procedure for this integration has been explained in depth. This would help the readers to integrate iBatis with Spring framework and thereby allow the objects specific to iBatis to make optimum use of the features available in the Spring framework.
If you have any questions on the spring framework integration with iBatis, please post it in the comments section. Also search in our website to find lot of other interesting articles related to the spring framework. There are some interesting articles about spring framework, interview questions, spring and hibernate integration,etc. If you are looking for the detailed knowledge, refer books for the spring framework.

If you would like to receive the future java articles from our website, please subscribe here.

Comments

comments

About Krishna Srinivasan

He is Founder and Chief Editor of JavaBeat. He has more than 8+ years of experience on developing Web applications. He writes about Spring, DOJO, JSF, Hibernate and many other emerging technologies in this blog.

Comments

  1. nice tutorials……really help me alot……

  2. dummies says:

    Hi,

    How do I set the system properties in where clause.

    For example if my query always retrieves records which is related local machine

    String machinename = InetAddress.getLocalHost().getHostName();

    Select * from syste_activity_log where machine_name=#machinename#

    Here instead of sending the machine name as parameter, is there anyway i could specify the system property in the query itself?

    something like

    Select * from syste_activity_log where machine_name= InetAddress.getLocalHost().getHostName()

  3. Hi,
    I get an error ” no bean class specified on bean definition ” when it tries to create jsrDao bean. Can you tell what could be wrong.

  4. Hi,
    I too got an error ” no bean class specified on bean definition ” when it tries to create jsrDao bean. Can you tell what could be wrong.
    Error Log pasted below

    “.BeanCreationException: Error creating bean with name ‘jsrDao’ defined in file [C:\Sathiya_project\MyIBatisProject\.\src\spring\ibatis\spring-ibatis.xml]: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [com.mrc.action.JsrDaoImpl]: Constructor threw exception; nested exception is java.lang.NoClassDefFoundError: com/ibatis/sqlmap/client/SqlMapExecutor”

  5. prakash says:

    Pls reply the ERROR
    Exception in thread “main” org.springframework.beans.factory.BeanCreationException: Error creating bean with name ‘jsrDao’ defined in file [spring-ibatis.xml]: Instantiation of bean failed; nested exception is java.lang.IllegalStateException: No bean class specified on bean definition
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:965)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:911)
    a

    Caused by: java.lang.IllegalStateException: No bean class specified on bean definition

Trackbacks

  1. […] How to integrate Spring with iBatis? […]

Speak Your Mind

*