Skip to content

Instantly share code, notes, and snippets.

@kannangce
Created August 27, 2018 10:22
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kannangce/5836d448ffcc0b49cb6e3cb80c043543 to your computer and use it in GitHub Desktop.
Save kannangce/5836d448ffcc0b49cb6e3cb80c043543 to your computer and use it in GitHub Desktop.
A generic ResultSetExtractor to be used with Spring's JdbcTemplate for any simple beans.
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.BiConsumer;
import java.util.function.Supplier;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.ResultSetExtractor;
/**
* Result set extractor to be used with Spring's
* {@link JdbcTemplate#query(String, ResultSetExtractor)} and other methods that
* uses a {@link ResultSetExtractor}.
*
* This result set extractor can be used with any simple bean of given generic
* instant <T>.
*
* @author kannan.r
*
* @param <T>
*/
public class GenericResultSetExtractor<T> implements ResultSetExtractor<List<T>>
{
private Map<String, BiConsumer<T, String>> itsBeanToSetterMap;
private Supplier<T> itsSupplier;
/**
* Instantiates the {@link GenericResultSetExtractor}
*
* @param theBeanToSetterMap
* The bean to setter map, with the keys as column names in upper
* case and the values as the {@link BiConsumer} instances that
* sets attribute for the respective column
* @param theInstanceSupplier
* The {@link Supplier} that creates the bean of the specific
* type.
*/
public GenericResultSetExtractor(Map<String, BiConsumer<T, String>> theBeanToSetterMap,
Supplier<T> theInstanceSupplier)
{
itsBeanToSetterMap = theBeanToSetterMap;
itsSupplier = theInstanceSupplier;
}
@Override
public List<T> extractData(ResultSet theRs) throws SQLException, DataAccessException
{
List<T> aResultList = new ArrayList<>();
while (theRs.next())
{
T anInstance = itsSupplier.get();
int aColCount = theRs.getMetaData().getColumnCount();
for (int anIndex = 1; anIndex <= aColCount; anIndex++)
{
String aCol = theRs.getMetaData().getColumnLabel(anIndex);
BiConsumer<T, String> aSetterMethod = itsBeanToSetterMap.get(aCol.toUpperCase());
aSetterMethod.accept(anInstance, theRs.getString(aCol));
}
aResultList.add(anInstance);
}
return aResultList;
}
/**
* Test user class for demo purpose.
*
* Class intended just for demo. Not part of the {@link ResultSetExtractor}
*/
public static class User
{
private int id;
private String name;
public int getId()
{
return id;
}
public void setId(int id)
{
this.id = id;
}
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
}
/**
* Method intended just for demo. Not part of the {@link ResultSetExtractor}
*/
public void demoUsage(JdbcTemplate aTemplate)
{
Map<String, BiConsumer<User, String>> aUserColumnToSetterMap = new HashMap<>();
aUserColumnToSetterMap.put("ID", (User u, String id) -> {
u.setId(Integer.parseInt(id));
});
aUserColumnToSetterMap.put("NAME", (User u, String name) -> {
u.setName(name);
});
GenericResultSetExtractor<User> anExtractor = new GenericResultSetExtractor<User>(
aUserColumnToSetterMap, () -> new User());
List<User> query = aTemplate
.query("SELECT ID, NAME FROM USERS WHERE USER.DEPT_ID='something'", anExtractor);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment