user2644922
user2644922

Reputation: 73

How to use MyBatis to map values from ResultSet to pojo

I have a legacy system, that uses plain old JDBC and MyBatis mixed. I already learned how to generate SQL using MyBatis (Can I use MyBatis to generate Dynamic SQL without executing it?) but can't find out how I could manually map the current row of java.sql.ResultSet to POJO.

I can't use MyBatis to do the full round trip, as the SQL query is fed to the legacy part as a string, but when I get the ResultSet back, I do know to which POJO it should be mapped to. (And the resultmap id). It would be wonderful to reuse the mappings from the mybatis config files, at the moment it's done by hand. (And thus the mapping logic is duplicated.)

Upvotes: 1

Views: 1657

Answers (1)

user2644922
user2644922

Reputation: 73

Florian's comment led me to the right direction, thanks for that! I did manage to get it working - not the cleanest solution, but it works.

Given java.sql.ResultSet rs containing x results, one can get the current one with the following code:

Object parameterObject = new Object();

RowBounds rb = new RowBounds(0, 1);
MappedStatement ms = sqlSession.getConfiguration().getMappedStatement("myBatisSelectId");
BoundSql boundSql = ms.getBoundSql(parameterObject);
ParameterHandler ph = new DefaultParameterHandler(ms, parameterObject, boundSql);
SimpleExecutor se = new SimpleExecutor(sqlSession.getConfiguration(), null);

DefaultResultHandler resultHandler = new DefaultResultHandler(sqlSession.getConfiguration().getObjectFactory());
DefaultResultSetHandler drsh = new DefaultResultSetHandler(se, ms, ph, resultHandler, boundSql, rb);

drsh.handleResultSets(new FakeStatement(new DelegatingNonClosingResultSet(rs)));
if (resultHandler.getResultList() == null || resultHandler.getResultList().isEmpty()) {
    return null;
}
return (T) resultHandler.getResultList().get(0);

Note that you do need the select id and the parameter object. Omitted code includes FakeStatement to carry the ResultSet and delegating ResultSet that delegates all methods except close, so we can manage ourselves when the ResultSet will be closed.

To get the next result one would call rs.next() and do all of the above again. Ofcourse many of the items can be reused.

Upvotes: 1

Related Questions