IBatis Introduction

You might also like

Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1of 9

iBatis Introduction

The first thing we need to know is:


What is iBatis ?

A JDBC Framework
o Developers write SQL, iBATIS executes it using JDBC.
o No more try/catch/finally/try/catch.

An SQL Mapper
o Automatically maps object properties to prepared statement parameters.
o Automatically maps result sets to objects.
o Support for getting rid of N+1 queries.

A Transaction Manager
o iBATIS will provide transaction management for database operations if no
other transaction manager is available.
o iBATIS will use external transaction management (Spring, EJB CMT, etc.) if
available.

Great integration with Spring, but can also be used without Spring (the Spring
folks were early supporters of iBATIS).

What isn't iBATIS ?

An ORM
o Does not generate SQL
o Does not have a proprietary query language
o Does not know about object identity
o Does not transparently persist objects
o Does not build an object cache

Essentially, iBatis is a very lightweight persistence solution that gives you most of the
semantics of an O/R Mapping toolkit, without all the drama. In other words ,iBATIS
strives to ease the development of data-driven applications by abstracting the lowlevel details involved in database communication (loading a database driver,
obtaining and managing connections, managing transaction semantics, etc.), as well
as providing higher-level ORM capabilities (automated and configurable mapping of
objects to SQL calls, data type conversion management, support for static queries as
well as dynamic queries based upon an object's state, mapping of complex joins to
complex object graphs, etc.). iBATIS simply maps JavaBeans to SQL statements using

a very simple XML descriptor. Simplicity is the key advantage of iBATIS over other
frameworks and object relational mapping tools.
Installing iBATIS is a quick and simple process. Because it is a library, and not an
application, there is no installation process, but you do need to go through a few steps
to use iBATIS in your application. You need to get the iBATIS library files. The entire
iBATIS framework can be downloaded from iBATIS homepage. iBATIS is delivered in a
single JAR file: ibatis-version.build.jar (as of now, ibatis-2.3.0.677.jar) and should be
copied and made available at runtime via the application's class path.
Configuring the Environment:
Lets see how to configure the iBatis-Spring environment. When working with
Spring and iBATIS, you will have a minimum of three XML configuration files, and you
will often have even more. It is important that you become familiar with these config
files. So how do you make iBATIS available to your application? There are a couple of
ways:
1. Using Spring - iBATIS with a stand-alone application:
You should place the ibatis-2.3.0.677.jar in the application's classpath. At
minimum, you must define and place the following three configuration files in
the classpath
o Spring config - This file defines the database connection parameters, the
location of the SQL Map config file, and one or more Spring beans for use
within the application. ( applicationContext.xml).
o SQL Map config - This file defines any iBATIS-specific configuration
settings that you may need and declares the location for any SQL Map
files that should be accessible through this config file. (SqlMapConfig.xml)
o

SQL Map(s) One or more SQL Map files are declared in the SQL Map
config and typically mapped to a single business entity within the application
,often represented by a single Java class (domainObject.xml).

2. Using Spring - iBATIS with a web application


Same as the above ,but just need one more xml (web.xml).
Now that we know the basic configuration steps,let's jump into example.
Spring - iBatis integration example
In this section, I?ll show you how to use Spring for iBatis. I?m assuming that you are
already familiar with Spring. If you are new to Spring or just need a refresher, I
recommend that you have a look at Spring tutorial.
This brief example will take you through a walkthrough of a typical use of SQL Maps as
well as Spring ? iBatis integration. The easiest place to start is to analyze what you?re
working with. What are your business objects? What are your database tables? How

do they relate to each other? For our example, consider the following simple Trade
class that conforms to the typical JavaBeans pattern.

Trade.java
package com.developersBook.iBatis.domain;
public class Trade {
private long tradeId;
private String action;
private String symbol;
private long shares;
private double price;
private String state;
public String getAction() {
return action;
}
public void setAction(String action) {
this.action = action;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public long getShares() {
return shares;
}
public void setShares(long shares) {
this.shares = shares;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
public String getSymbol() {
return symbol;
}
public void setSymbol(String symbol) {
this.symbol = symbol;
}
public long getTradeId() {

return tradeId;
}
public void setTradeId(long tradeId) {
this.tradeId = tradeId;
}
public String toString() {
return ("TRADE " + tradeId + ": " + action + ", " + symbol + ", "
+ shares + " shares, $" + price + "/share (" + state + ")");
}
}
Let?s use the following simple table which would be suitable for a table-per-class
relationship:
CREATE TABLE TRADE (
TRADE_ID NUMBER (5, 0) NOT NULL,
SIDE VARCHAR (10) NOT NULL,
SYMBOL VARCHAR (6) NOT NULL,
SHARES NUMBER (4, 2) NOT NULL,
PRICE NUMBER (4, 2) NOT NULL,
STATE VARCHAR (20) NOT NULL,
PRIMARY KEY (TRADE_ID)
)
Once we?re comfortable with the classes and tables we?re working with, the best
place to start is the Spring configuration file. The configuration file is an XML file
(applicationContext.xml). Within it we will configure properties, JDBC DataSources. It
gives you a nice convenient location to centrally configure your DataSource which can
be any number of different implementations. The framework can handle a number of
DataSource implementations including iBATIS SimpleDataSource, Jakarta DBCP
(Commons), and any DataSource that can be looked up via a JNDI context (e.g. from
within an app server).
applicationContext.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"
class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName"
value="oracle.jdbc.driver.OracleDriver" />
<property name="url"
value="jdbc:oracle:thin:@127.0.0.1:1521:orcl" />
<property name="username" value="scott" />

<property name="password" value="tiger" />


</bean>
<bean id="sqlMap"
class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
<property name="configLocation">
<value>classpath:SqlMapConfig.xml</value>
</property>
<property name="dataSource" ref="dataSource" />
</bean>
<bean id="tradingService"
class="com.developersBook.iBatis.service.TradeServiceImpl">
<property name="sqlMapClient" ref="sqlMap" />
</bean>
</beans>
Dont worry too much about the tradingService details right now. Soon, Ill explain
more about what is going on here. Observe the Spring configuration xml,
the sqlMap property must be wired with a reference to an iBATIS SqlMap-Client. In
Spring, the best way to get an SqlMapClient is through SqlMapClientFactoryBean:

<bean id="sqlMap"
class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
<property name="configLocation">
<value>classpath:SqlMapConfig.xml</value>
</property>
<property name="dataSource" ref="dataSource" />
</bean>
SqlMapClientFactoryBean is a Spring factory bean that produces an SqlMapClient. The
dataSource property is wired with a reference to a javax.sql.DataSource.
Defining iBATIS SQL maps
As for the configLocation property, it should be configured with the path to an XML file
that enumerates the locations of the iBATIS SQL maps. For the trade application, Ive
defined one SQL map file per domain object. Therefore, the sql-map-config.xml file will
look like this:

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>
<settings useStatementNamespaces="true"/>
<sqlMap resource="TradingSQLMap.xml"/>
</sqlMapConfig>
The SQL map file is loaded as resources from the classpath under the same package
as the domain object.
Now that we have a DataSource configured and our central configuration file is ready
to go, we will need to provide the actual SQL Map file which contains our SQL code
and the mappings for parameter objects and result objects (input and output
respectively). Continuing with our example above, let?s build an SQL Map file for the
Trade class and the TRADE table. We?ll start with the general structure of an SQL
document, and a simple select statement:

TradingSQLMap.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sqlMap PUBLIC "-//iBATIS.com//DTD SQL MAP 2.0//EN"
"http://www.ibatis.com/dtd/sql-map-2.dtd">
<sqlMap namespace="trading">
<typeAlias alias="trade" type="com.developersBook.iBatis.domain.Trade"/>
<cacheModel id="tradeCache" type="LRU" readOnly="true">
<flushInterval hours="24"/>
<flushOnExecute statement="trading.executeTrade"/>
<property name="cache-size" value="1000"/>
</cacheModel>
<resultMap id="tradeResult" class="trade">
<result property="tradeId" column="TRADE_ID"/>
<result property="action" column="SIDE"/>
| Defines
<result property="symbol" column="SYMBOL"/>
| result
<result property="shares" column="SHARES"/>
| mapping
<result property="price" column="PRICE"/>
<result property="state" column="STATE"/>
</resultMap>
<select id="getTrade" parameterClass="long" resultMap="tradeResult"
cacheModel="tradeCache">
SELECT
TRADE_ID,
SIDE,
SYMBOL,
| Declares
SHARES,
| getTrade
PRICE,
| query
STATE

FROM
TRADE
WHERE
TRADE_ID = #id#
</select>
<!-- Use Trade object (JavaBean) "id" properties as parameters for update. Each of the
parameters in the #hash# symbols is a JavaBeans property. -->
<update id="executeTrade" parameterClass="long">
UPDATE
TRADE
SET
STATE = 'EXECUTED'
| Declares
WHERE
| executeTrade(update)
TRADE_ID = #id#
| query
</update>
</sqlMap>
Now that we are all configured and mapped, all we need to do is code it in our Java
application. Lets start with service layer.
ITradeService.java
package com.developersBook.iBatis.service;
import com.developersBook.iBatis.domain.Trade;
public interface ITradeService {
public Trade getTrade(long tradeId)throws Exception ;
public void executeTrade(long tradeId) throws Exception;
}
TradeServiceImpl class implements ITradeService interface.
TradeServiceImpl.java
package com.developersBook.iBatis.service;
import com.developersBook.iBatis.domain.Trade;
import com.ibatis.sqlmap.client.SqlMapClient;
public class TradeServiceImpl implements ITradeService {
protected SqlMapClient sqlMap = null;
public void setSqlMapClient(SqlMapClient sqlMap) {

this.sqlMap = sqlMap;
}
public Trade getTrade(long tradeId) throws Exception {
return (Trade)sqlMap.queryForObject("trading.getTrade", tradeId);
}
public void executeTrade(long tradeId) throws Exception {
sqlMap.update("trading.executeTrade", tradeId);
}
}
Let's code the client to test this Spring - iBatis integration.
IBatisClient.java
package com.developersBook.iBatis.client;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.developersBook.iBatis.service.ITradeService;
public class IBatisClient {
public static void main(String[] args) {
try {
System.out.println("IBatisClient started");
System.out.println(" ");
// load spring beans
ApplicationContext ctx = new ClassPathXmlApplicationContext(
"applicationContext.xml");
System.out.println("Classpath loaded");
System.out.println(" ");
ITradeService service = (ITradeService) ctx
.getBean("tradingService");
// getTrade
int tradeId = 1;
System.out.println("BEFORE: " + service.getTrade(tradeId));
// update trade
service.executeTrade(tradeId);
System.out.println("AFTER : " + service.getTrade(tradeId));
System.out.println(" ");
System.out.println("Hurry!!!! Its done!");
} catch (Exception e) {
e.printStackTrace();
}

}
}

You might also like