Implementing dynamic SQL on Mybatis

Mybatis supports dynamic sql by using if, choose or when tag inside mapper xml. (More on dynamic sql tags) Sometimes, however, such tags are not enough for some requirements. Some times ago, I had to build select statements based on random table name. In that case, all parts of select statement were really dynamic. But condition tags inside mapper xml could not meet the requirements.

Mybatis supports really dynamic sql by @SelectProvider, @InsertProvider, @UpdateProvider and @DeleteProvider. I am showing a short example. (Download full sample)

Test table

CREATE TABLE MYBATIS_TEST(
	COL1 VARCHAR2(10) PRIMARY KEY,
	COL2 VARCHAR2(10)
);

SQL builder class

package test.mapper;

public class QueryBuilder {
	public String getSql() {
		String sql = "SELECT COL1, COL2 FROM MYBATIS_TEST WHERE COL1 = #{COL1}";
		return sql;
	}
}
  • Above sql builder is very simple. But you can apply really dynamic logic inside it.

Mapper class

package test.mapper;

import org.apache.ibatis.annotations.SelectProvider;
import java.util.Map;

public interface TestMapper {
	@SelectProvider(type=QueryBuilder.class, method="getSql")
	public Map selectARecord(String key);
}
  • This mapper class is the core of the sample. The important point is using @SelectProvider and it’s “type” and “method” attribute (which are pointing sql builder class and it’s method)

Mybatis config.xml

mybatis-config.xml

  • Above config.xml defines mapper class by using mapper tag and class attribute.

Test main app

package test;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.apache.log4j.Logger;
import java.io.InputStream;

import test.mapper.TestMapper;
import java.util.Map;

public class TestDynamicSql {
	private Logger logger = Logger.getLogger(this.getClass());

	public static void main(String [] args) throws Exception{
<span id="mce_SELREST_start" style="overflow:hidden;line-height:0;"></span>		TestDynamicSql testApp = new TestDynamicSql();
		testApp.testDynamicSql();
	}

	private SqlSessionFactory getSqlSessionFactory() throws Exception{
		String resource = "mybatis-config.xml";
		InputStream inputStream = Resources.getResourceAsStream(resource);
		return new SqlSessionFactoryBuilder().build(inputStream);
	}

	private void testDynamicSql() throws Exception{
		SqlSessionFactory sessionFactory = getSqlSessionFactory();
		SqlSession sqlSession = sessionFactory.openSession(true);
		TestMapper mapper = sqlSession.getMapper(TestMapper.class);
		Map recordMap = mapper.selectARecord("VALUE1");
		this.logger.info("COL2 Value : " + recordMap.get("COL2"));
		sqlSession.close();
	}

}

 

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.