Tag Archives: ibatis

I was given a task to work on Ms Access database. I had to choose either JDBC, iBatis and Hibernate for the persistence mechanic. So I tried each of them to see which one is the best.

First, I worked with JDBC with Spring. Below is one of the query where I mapped the result to Country object.

public class CountryDaoJdbcImpl extends AbstractJdbcDao implements CountryDao {

    public List getAllCountries() {

        List countries = getJdbcTemplate().
                query(
                "SELECT * FROM Country_Code", new RowMapper() {

            public Object mapRow(ResultSet rs, int rowNum)
                    throws SQLException, DataAccessException {
                Country country = new Country();
                country.setCode(rs.getString(1));
                country.setName(rs.getString(2));
                country.setIsdCode(rs.getString(3));
                return country;
            }
        });

        return countries;
    }
}

It is easy to implement but the code is too verbose. Plus, if I have relationships between objects, the code will be more complicated and maintenance would be tough.

Then, I tried to implement iBatis with Spring. Below is the iBatis config for an object with a relationship with another object.

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

    <resultMap id="CategoryResultMap" class="Category" groupBy="categoryCode">
        <result property="categoryCode" column="categoryCode" />
        <result property="description" column="description" />
    </resultMap>    

    <resultMap id="SubCategoryResultMap" class="SubCategory" groupBy="subCategoryCode">
        <result property="subCategoryCode" column="subCategoryCode" />
        <result property="description" column="description" />
        <result property="categoryCode" column="categoryCode" />
        <result property="category"
                column="categoryCode"
                select="General.getCategoryByCategoryCode" />
    </resultMap>

    <select id="getAllCountries" resultClass="Country">
        SELECT
        country_code as code, name, isd_code as isdCode
        FROM
        country_code
    </select>   

    <select id="getAllSubCategories" resultMap="SubCategoryResultMap">
        SELECT
        sub_category_code as subCategoryCode,
        sub_category_name as description,
        category_code as categoryCode
        FROM
        sub_category_code
    </select>  

    <select id="getCategoryByCategoryCode" parameterClass="string"
            resultMap="CategoryResultMap" >
        SELECT
        category as categoryCode,
        description
        FROM
        category_code
        WHERE
        category = #value#
    </select>

</sqlMap>

Above is the iBatis config for a SubCategory object that has a Category object as a parent.

public class SubCategoryDaoIbatisImpl extends AbstractIbatisDao implements SubCategoryDao{

    public SubCategoryDaoIbatisImpl(DaoManager daoManager){
        super(daoManager);
    }

    @Override
    public List<SubCategory> getAllSubCategories() throws SQLException {
        return getSqlMapExecutor().queryForList("General.getAllSubCategories", null);
    }
}

Above is the query made via SqlMapExecutor, but this doesn’t work with MS Access. When I migrated the database to MySQL, it worked fine. So, iBatis is a NO too for Ms Access.

My last resort was Hibernate with Spring. Below is my code for the same object above.

...

/**
* @author Taufek
*/
@Entity
@Table(name = "sub_category_code")
public class SubCategory extends AbstractEntity {

private Category category;
private String subCategoryCode;
private String description;

@ManyToOne(cascade = {CascadeType.PERSIST, CascadeType.MERGE}, fetch = FetchType.EAGER)
@JoinColumn(name = "category_code")
public Category getCategory() {
return category;
}

public void setCategory(Category category) {
this.category = category;
}

@Column(name = "sub_category_name")
public String getDescription() {
return description;
}

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

@Id
@Column(name = "sub_category_code")
public String getSubCategoryCode() {
return subCategoryCode;
}

public void setSubCategoryCode(String subCategoryCode) {
this.subCategoryCode = subCategoryCode;
}
...
}

Above is the SubCategory object.

...
/**
* @author Taufek
*/
@Entity
@Table(name="category_code")
public class Category extends AbstractEntity{

private String categoryCode;
private String description;

@Id
@Column(name="category")
public String getCategoryCode() {
return categoryCode;
}

public void setCategoryCode(String code) {
this.categoryCode = code;
}

@Column(name="description")
public String getDescription() {
return description;
}

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

Above is Category object which is the parent of SubCategory.

public class SubCategoryDaoHibernateImpl extends AbstractHibernateDao implements SubCategoryDao{

    public List getAllSubCategories() throws SQLException {
        return getHibernateTemplate().loadAll(SubCategory.class);
    }

}

Above is the query. It is simpler with Hibernate. I only need to put the Hibernate annotations on each property in an entity to map it to its counterpart in the database. Then, by using HibernateTemplate from Spring, just use one of the methods provided to make a query.

I thought, I was done with choosing persistence method, but whenever there is an object which has more than 1 relationship, the query will return error. I found out that whenever there is a query with a relationship, hibernate will construct a query consists of LEFT OUTER JOIN to combine between 2 tables. I was surprised to find out that MS Access query can only has 1 LEFT OUTER JOIN. If you run a query with more than 1 LEFT OUTER JOIN, it will return an error.

So now,I’m back to square one with ol’ JDBC.

Currently, I’m learning on how to incorporate iBatis into my application’s persistence layer. iBatis relies heavily on its xml files, which are used to map the SQLs to Java objects. If your project, contains a large number of tables, this could be a problem. You have to hand-code all the Java objects and SQLs manually. Being a self proclaimed Gung-Ho of open source technologies, I believe there must be something out there that could ease this burden. Well, there is!

There is a tool which was known as Abator, and was renamed to iBator. Wondering why changed the name? It was stated at the iBator web site, it was due to trade registration dispute. Well, changed name doesn’t affect the functionality at all. Functionally, iBator helps to generate the SQL Map Xmls and Java files based on the existing tables. Not only that, it could also generates DAO layer for you. It could tailor your DAO layer according to the Spring DAO standards. All you need to do after this, is tweak a bit on the generated xml files and connect your service layer to the DAO layer. How’s that for a speed in your project.

Basically, you will need one jar file, iBator jar. It doesn’t has any dependencies. But in my case, I would need ant jar file, since I’m using ant to execute the generator.

First, I would need the abatorConfig.xml file. Below is how I set the database connection settings:

Then, there are 3 items I’m setting below. First element, is the Java objects’ settings. Second element, is the SQLs xml files’ settings. And the third element, is the DAOs settings. Here you have to specify the target locations and the package/folder names for the generated files.
Generated Files Configs

Third, is my tables settings. Here I mapped the tables to my Java objects:
Tables Configs

Lastly, I just need to execute below ant file:
iBator Ant Build

That’s it. After running above ant build, you would have the almost complete DAO layer for your application. Some extra work might be needed such as configuring your tables relationship, setting your SQLMapConfig, and connecting your DAO layer to your service layer.

As with any other generator utility, it won’t gives you the perfect generated files. Some level of tweaking is expected from you. But to kick start a project with lots of tables, for sure you could appreciate the benefits of this utility.

I’ve been to couple of Java technical interviews that asked about iBatis. Frustrated with my lack of knowledge on the matter, I just had to tell the interviewer that I’d never work on the framework before. iBatis must be popular enough and worth the time for me to check it out. So, after working with the starter guide, here’s what I’ve learned.

Unlike other ORM (Object-Relational Mapping) frameworks such as Hibernate, which reduces dramatically number of SQLs for the developer, iBatis works closely with SQL. It SQL-like syntax gives you more control over your relationships between your relational database and your POJO. It’s also lightweight and requires minimal effort to jack it up into your application. Basically, it only requires one jar file (since it came bundled with its dependencies) and 2 XML configuration files, to be located in your application classpath.

First off, the SqlMapConfig.xml file.
SqlMapConfig.xml

As you can see, this is where the general configurations of IBatis are located.

Second, the SqlMap.xml file, where you put your sql mappings.
SqlMap.xml

Here, I’ve created a select mapping and as you can see, it uses native SQL. So, if you’re an avid users of SQL, this would not be a problem to interpret.

Lastly, I’ve create a test class, to make a test call on above select mapping.
QueryTest.java

In the init method, it loads the configuration file called SqlMapConfig.xml and in the getPersonQuery test method, is where the magic happens. The queryForObject method uses getPerson select mapping, which I’ve declared in SqlMap.xml file and it should returns a Person object.

That’s it and now my application persistence layer is under iBatis. If I run the test class, It should print out the person instance that I’ve queried on my console:
Query Output

So iBatis is great and all but the question is, when do you choose iBatis over other ORMs? If you, as a developer, have full control over your domain objects design, ORM might me the best choice for you. But, if you are working on an existing database structure or there is a possibility that your database layer might me under different team responsibility, then iBatis will be a good choice. Hmm… maybe I’ll stuff iBatis into my new upcoming project just for the fun of it.