Multiple Results
The multipleExecute series of methods in JdbcTemplate solves the problem of SQL statements producing multiple values that are hard to identify and retrieve.
When It Happens
- Sending multiple unsplit SQL statements in a single request.
Example: send the entire block to MySQLset @userName = convert(? USING utf8);select * from test_user where name = @userName;select * from test_user where name != @userName;info
Some databases (e.g., MySQL) require enabling multi-statement support, such as
allowMultiQueries=truein the JDBC URL. - Stored procedures returning multiple result sets, intentionally or not.
Example: MySQL procedure yielding two result setscreate procedure proc_multi_result(in userName varchar(200))beginselect * from test_user where name = userName;select * from test_user where name != userName;end;
- Other situations that produce multiple result sets.
Usage
One argument, two result sets: matches vs mismatches
String multipleSql = " set @userName = convert(? USING utf8);" +
" select * from test_user where name = @userName;" +
" select * from test_user where name != @userName;";
Map<String, Object> result = jdbc.multipleExecute(multipleSql, "muhammad");
- See Arguments for all supported binding styles.
Return Value
- By default, each result set is represented as List/Map: a
List<Map<String, Object>>stored alongside update counts in the returnedMap<String, Object>. Without an explicit name, keys are#result-set-Nor#update-count-N, where N is the result's position starting at 1. - You can embed rules in SQL to control how each result set is handled.
1. Annotate statements with @{resultSet} rules
set @userName = convert(? USING utf8); @{resultUpdate,name=upd}
select * from test_user where name = @userName; @{resultSet,name=res1,javaType=net.demo.dto.User}
select * from test_user where name != @userName; @{resultSet,name=res2,javaType=net.demo.dto.User}
Explanation:
- The SET statement uses a rule to label the update count as
upd. - The first SELECT uses a rule to label its result set
res1and map rows tonet.demo.dto.User. - The second SELECT uses a rule to label its result set
res2and map rows tonet.demo.dto.User.
2. Execute annotated SQL and fetch typed results
String query = "set @userName = convert(? USING utf8); @{resultUpdate,name=upd}" +
"select * from test_user where name = @userName; @{resultSet,name=res1,javaType=net.demo.dto.User}" +
"select * from test_user where name != @userName; @{resultSet,name=res2,javaType=net.demo.dto.User}";
Map<String, Object> result = jdbcTemplate.multipleExecute(query, "muhammad");
List<User> result1 = (List<User>) result.get("res1"); // First SELECT
List<User> result2 = (List<User>) result.get("res2"); // Second SELECT
info
See RESULT rule for more on @{resultSet,...}.
info
multipleExecutereturns aLinkedCaseInsensitiveMaporLinkedHashMapto preserve statement order.- See Map Case Sensitivity for details.