When we talk about the persistence framework, we think in Hibernate/JPA. Recently I was presented to iBatis, a framework that so easy to install, to configure and to use. You can download it in your sponsor site, Apache, clicking here.
Setting iBatis
Unlike another frameworks, to configure iBatis you need only one XML file, called SqlMapConfig.
The mains sections of XML are:
<properties resource="tuto/ibatis/config/SqlMap.properties"/>
This code is optional and specifies the .properties file that’ll be used to declare variables used in configuration.
<typeAlias alias="car" type="tuto.ibatis.beans.Car"/>
Defines the JavaBean used and your alias. You can set much lines, depending of modeling complexity.
In example, we’ll Car bean below:
public class Car {
private Long carId;
private String company;
private String model;
private String color;
private Integer hp;
private Float price;
//Setters and getters omitted
}
<transactionManager type="JDBC">
<dataSource type="SIMPLE">
<property name="JDBC.Driver" value="${driver}"/>
<property name="JDBC.ConnectionURL" value="${url}"/>
<property name="JDBC.Username" value="${username}"/>
<property name="JDBC.Password" value="${password}"/>
</dataSource>
</transactionManager>
Parameters used in database connection. The variables ${driver}, ${url}, ${username} and ${password} are defined in .properties file in section properties. If you prefer, can put the values directly in fields.
See the complete file:
<?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>
<properties resource="tuto/ibatis/config/SqlMap.properties"/>
<settings
cacheModelsEnabled="true"
enhancementEnabled="true"
lazyLoadingEnabled="true"
maxRequests="32"
maxSessions="10"
maxTransactions="5"
useStatementNamespaces="false" />
<typeAlias alias="car" type="tuto.ibatis.beans.Car"/>
<transactionManager type="JDBC">
<dataSource type="SIMPLE">
<property name="JDBC.Driver" value="${driver}"/>
<property name="JDBC.ConnectionURL" value="${url}"/>
<property name="JDBC.Username" value="${username}"/>
<property name="JDBC.Password" value="${password}"/>
</dataSource>
</transactionManager>
<sqlMap resource="tuto/ibatis/sqlmaps/CarSqlMap.xml"/>
</sqlMapConfig>
The properties have this content:
driver=oracle.jdbc.OracleDriver url=jdbc:oracle:thin:@<host>:<porta>:<sid> username=<login> password=<senha>
Next you need to configure the SqlMap. This XML contains the querys used in application and your name need be equals described in sqlMap section of SqlMapConfig, in our case will be CarSqlMap.xml
In example only we will see utilization of tags select, insert, update and delete.
<select id="getCars" resultClass="tuto.ibatis.beans.Car"
parameterClass="java.lang.Long">
SELECT COMPANY as company,
MODEL as model,
COLOR as color,
HP as hp,
PRICE as price
FROM TBL_CAR
WHERE CAR_ID = #var#
</select>
Execute the select statement can return a single object or one collection of objects, the type is same of resultClass attribute, o parameterClass is the type sent to execute the query and the id is the query identification call.
We will use the SqlMap below:
<?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="Car">
<select id="getCars" resultClass="tuto.ibatis.beans.Car"
parameterClass="java.lang.Long">
SELECT COMPANY as company,
MODEL as model,
COLOR as color,
HP as hp,
PRICE as price
FROM TBL_CAR
WHERE CAR_ID = #var#
</select>
<insert id="addCar" parameterClass="tuto.ibatis.beans.Car">
INSERT INTO TBL_CAR (CAR_ID, COMPANY, MODEL, COLOR, HP, PRICE)
VALUES (#carId#, #company#, #model#, #color#, #hp#, #price#)
</insert>
<delete id="delCar" parameterClass="java.lang.Long">
DELETE FROM TBL_CAR WHERE CAR_ID = #var#
</delete>
<update id="updCar" parameterClass="tuto.ibatis.beans.Car">
UPDATE TBL_CAR
SET COMPANY = #company#,
MODEL = #model#,
COLOR = #color#,
HP = #hp#,
PRICE = #price#
WHERE CAR_ID = #carId#
</update>
</sqlMap>
Data base connection configured, now we will implements the singleton class the will used as SqlMapClient, called OracleMapConfig.
package tuto.ibatis.connection;
import java.io.Reader;
import com.ibatis.common.resources.Resources;
import com.ibatis.sqlmap.client.SqlMapClient;
import com.ibatis.sqlmap.client.SqlMapClientBuilder;
public class OracleMapConfig {
private static final SqlMapClient sqlMapClient;
static{
try{
//Defining path of SqlMapConfig and creating reader
String res = "tuto/ibatis/config/SqlMapConfig.xml";
Reader reader = Resources.getResourceAsReader(res);
//Retrieving the client to SqlMap
sqlMapClient = SqlMapClientBuilder.buildSqlMapClient(reader);
} catch(Exception e){
e.printStackTrace();
throw new RuntimeException(e);
}
}
//Method used to retrieve the client
public static SqlMapClient getSqlMapClient(){
return sqlMapClient;
}
}
The client is responsible for execute the querys configured in SqlMap and return the results.
Executing Querys and treating the return
To call any query is too simple, only execute the correspondent method of client class.
The select can be called this way:
OracleMapConfig.getSqlMapClient().queryForObject("<id>", <parâmetro>);
Theid need be equals of id specified in SqlMap
Only one line is return in code above, to get all lines change to queryForList, this way:
OracleMapConfig.getSqlMapClient().queryForList("<id>", <parâmetro>);
Will be returned a Collection containing the objects;
Select
try{
Car car = (Car)OracleMapConfig.getSqlMapClient().queryForObject("getCars",
new Long(readKeyboard()));
System.out.println("Company: "+car.getCompany());
System.out.println("Model: "+car.getModel());
System.out.println("Color: "+car.getColor());
System.out.println("HP: "+car.getHp());
System.out.println("Price: "+car.getPrice());
}catch (Exception e) {
e.printStackTrace();
}
The id “getCars” are defined in select attributes of SqlMap, providing one Long type and retrieving a Car type, both defined in line <select id=”getCars” resultClass=”tuto.ibatis.beans.Car” parameterClass=”java.lang.Long“>.
Insert
try{
OracleMapConfig.getSqlMapClient().insert("addCar", newCar);
}catch (Exception e) {
e.printStackTrace();
}
Now we will provide as parameter a Car type, <insert id=”addCar” parameterClass=”tuto.ibatis.beans.Car“>, and call the methods using sharp (#), this way:
INSERT INTO TBL_CAR (CAR_ID, COMPANY, MODEL, COLOR, HP, PRICE) VALUES (#carId#, #company#, #model#, #color#, #hp#, #price#)
Delete
try{
int lines = OracleMapConfig.getSqlMapClient().delete("delCar",
new Long(readKeyboard()));
System.out.println(lines + " lines deleted");
}catch (Exception e) {
e.printStackTrace();
}
The method delete of client return a type int, this represents the number of rows deleted.
Update
try{
int lines = OracleMapConfig.getSqlMapClient().update("updCar", car);
System.out.println(lines + " cars updated");
}catch (Exception e) {
e.printStackTrace();
}
Update return a type int, this represents the number of rows affected by update.
How you see, with only three XML and three classes we built a simple storage management and price consulting system.
You can download the source code of this tutorial clicking here.
Until next post!
March 4th, 2010 on 10:51
Short and very clear. Probably your intentionally omitted OracleMapConfig’s default constructor. Thanks a lot.
December 15th, 2011 on 12:55
This still is helpful!!
Thank you so much!
December 15th, 2011 on 13:03
You’re welcome!!