Skip to main content

Receiving Results

dbVisitor provides multiple ways to process query results. Most scenarios are handled by default mapping; for special requirements, you can customize result processing.

Quick Reference​

Your NeedRecommended ApproachDescription
Return a list of entity objectsqueryForList(User.class)Automatic conversion based on object mapping
Return a single entity objectqueryForObject(User.class)Use when there is only one record
No entity class needed, use MapJdbcTemplate queryForList(sql) / queryForMap(sql)Column name → Map key
Fetch only one column's valuesqueryForList(String.class)Single-column result set
Fetch only one valuequeryForObject(Integer.class)COUNT results, etc.
Process row by row without collectingRowCallbackHandlerStreaming / large data volumes
Full control over ResultSetResultSetExtractorCustom aggregation logic
PaginationPageObject + pageBySampleIncludes total record count and total pages

Basics: Direct Mapping to Entity or Map​

Query entity object list
List<User> users = jdbc.queryForList("select * from users where age > ?", 18, User.class);
Query a single entity
User user = jdbc.queryForObject("select * from users where id = ?", 1, User.class);
Use Map when no entity class is needed
Map<String, Object> row = jdbc.queryForMap("select * from users where id = ?", 1);
List<Map<String, Object>> rows = jdbc.queryForList("select * from users");

Fetch a Single Column or Single Value​

Fetch all values of a single column
List<String> names = jdbc.queryForList("select name from users", String.class);
Fetch a single value (e.g., COUNT)
int count = jdbc.queryForObject("select count(*) from users", Integer.class);

Row-by-Row Processing (for Large Data Volumes)​

RowCallbackHandler consumes rows without collecting a result list in the framework. The driver may still buffer results; configure its cursor or fetchSize for large queries and avoid accumulating data in the callback:

jdbc.query("select * from users", (RowCallbackHandler) (rs, rowNum) -> {
String name = rs.getString("name");
processRow(name); // Processed and discarded immediately
});

Fully Custom ResultSet Processing​

ResultSetExtractor<Map<Integer, String>> extractor = rs -> {
Map<Integer, String> result = new HashMap<>();
while (rs.next()) {
result.put(rs.getInt("id"), rs.getString("name"));
}
return result;
};

Map<Integer, String> idNames = jdbc.query("select * from users", extractor);

Result Processing in the Builder API​

LambdaTemplate supports the same result processing approaches:

// Entity list
List<User> users = lambda.query(User.class).eq(User::getAge, 18).queryForList();

// Map list
List<Map<String, Object>> rows = lambda.query(User.class).eq(User::getAge, 18).queryForMapList();

// Custom RowMapper
RowMapper<UserVO> rowMapper = new BeanMappingRowMapper<>(UserVO.class);
List<UserVO> vos = lambda.query(User.class).eq(User::getAge, 18).queryForList(rowMapper);

// ResultSetExtractor
ResultSetExtractor<Map<Integer, String>> extractor = rs -> { ... };
Map<Integer, String> result = lambda.query(User.class).query(extractor);

// RowCallbackHandler
lambda.query(User.class).query((rs, rowNum) -> { ... });

Pagination Results​

PageObject page = new PageObject(0, 20); // Page 0, 20 records per page

// LambdaTemplate pagination
List<User> users = lambda.query(User.class)
.gt(User::getAge, 18)
.usePage(page)
.queryForList();

// BaseMapper pagination (returns PageResult with statistics)
PageResult<User> result = mapper.pageBySample(sample, page);
long totalRecords = result.getTotalCount();
long totalPages = result.getTotalPage();

Further Reading​

  • RowMapper: Row-by-row mapping, including built-in BeanMappingRowMapper, ColumnMapRowMapper, SingleColumnRowMapper
  • Map Structures: Receive data directly as Map<String, Object> without defining entity classes
  • ResultSetExtractor: Full control over ResultSet traversal and transformation
  • RowCallbackHandler: Row-by-row callbacks without collecting results, suitable for streaming scenarios
  • Pagination Object: Creating, paging, and statistics of PageObject