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.