DEV Community

Said Olano
Said Olano

Posted on

iBatis: A Practical Guide to the SQL Mapper Framework (2026-08-17 22:12)

iBatis: SQL Mapper Framework

When it comes to persistence frameworks in the Java ecosystem, the conversation often gravitates toward full ORM solutions like Hibernate. However, there's a whole category of developers who prefer to keep their SQL close and their control tighter. This is where iBatis (now continued as MyBatis) shines.

In this post, we'll explore what iBatis is, how it differs from traditional ORMs, and how to get started with it.

What Is iBatis?

iBatis is a SQL Mapper framework. Rather than generating SQL for you like a traditional Object-Relational Mapping (ORM) tool, iBatis lets you write your own SQL statements and maps the results to Java objects (and vice versa).

The core philosophy is simple:

You write the SQL. iBatis handles the boilerplate of parameter binding and result mapping.

This gives you the productivity benefits of automated data mapping while retaining full control over your queries.

iBatis vs. Full ORM

Understanding when to use iBatis comes down to understanding the trade-offs:

Aspect iBatis (SQL Mapper) Hibernate (ORM)
SQL Control Full — you write it Generated (mostly)
Learning Curve Gentle Steeper
Complex Queries Excellent Can be awkward
Caching Basic Advanced
Legacy DB Support Excellent Requires adaptation

If you're working with a legacy database, stored procedures, or highly optimized queries, iBatis is often the better fit.

Core Components

An iBatis-based application typically involves the following pieces:

  1. SqlMapConfig.xml — the main configuration file (datasource, transaction manager, and references to mapper files).
  2. SQL Map XML files — where you define your SQL statements and mappings.
  3. Domain objects (POJOs) — plain Java classes representing your data.
  4. SqlMapClient — the runtime API used to execute mapped statements.

Configuration Example

Here's a minimal 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>
    <transactionManager type="JDBC">
        <dataSource type="SIMPLE">
            <property name="JDBC.Driver" value="com.mysql.jdbc.Driver"/>
            <property name="JDBC.ConnectionURL" value="jdbc:mysql://localhost/appdb"/>
            <property name="JDBC.Username" value="root"/>
            <property name="JDBC.Password" value="secret"/>
        </dataSource>
    </transactionManager>

    <sqlMap resource="com/example/maps/User.xml"/>
</sqlMapConfig>
Enter fullscreen mode Exit fullscreen mode

Defining a SQL Map

Let's map a simple User domain object. First, the POJO:

public class User {
    private int id;
    private String username;
    private String email;

    // getters and setters omitted for brevity
}
Enter fullscreen mode Exit fullscreen mode

Now the corresponding User.xml map file:

<?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="User">

    <resultMap id="userResult" class="com.example.User">
        <result property="id" column="user_id"/>
        <result property="username" column="username"/>
        <result property="email" column="email"/>
    </resultMap>

    <select id="getUserById" parameterClass="int" resultMap="userResult">
        SELECT user_id, username, email
        FROM users
        WHERE user_id = #value#
    </select>

    <insert id="insertUser" parameterClass="com.example.User">
        INSERT INTO users (username, email)
        VALUES (#username#, #email#)
    </insert>

</sqlMap>
Enter fullscreen mode Exit fullscreen mode

Notice the #value# and #username# placeholders. These are inline parameters that iBatis safely binds using prepared statements, protecting you from SQL injection.

Executing Statements

With the mapping in place, you can execute statements through the SqlMapClient:

Reader reader = Resources.getResourceAsReader("SqlMapConfig.xml");
SqlMapClient sqlMap = SqlMapClientBuilder.buildSqlMapClient(reader);

// Query a single user
User user = (User) sqlMap.queryForObject("getUserById", 1);

// Insert a new user
User newUser = new User();
newUser.setUsername("jdoe");
newUser.setEmail("jdoe@example.com");
sqlMap.insert("insertUser", newUser);
Enter fullscreen mode Exit fullscreen mode

Dynamic SQL

One of iBatis's standout features is dynamic SQL. You can build queries conditionally based on the parameters provided:


xml
<select id="searchUsers" parameterClass="java.util.Map" resultMap="userResult">
    SELECT user_id, username, email
    FROM users
    <dynamic prepend="WHERE">
        <isNotNull property="username">
            username = #username#
        </isNotNull>
        <isNotNull property="email" prepend="AND">
            email = #email#
        </isNotNull>
    </dynamic
Enter fullscreen mode Exit fullscreen mode

Top comments (0)