JdbcTemplate provides a number of overloaded template methods for data queries, and you can choose different template methods as needed. If your query is simple, just pass in the appropriate SQL or related parameters and get a single result, you can choose the following set of handy template methods:
int queryForInt (String sql)
int queryForInt (String sql, object[] args)
Long queryForLong (String sql)
Long queryForLong (String sql, object[] args)
Object queryForObject (String sql, Class requiredtype)
Object queryForObject (String sql, object[] args, Class requiredtype)
Map queryForMap (String sql)
Map queryForMap (String sql, object[] args)
For example, the result of your query contains a list of numeric results, or the use of SQL functions, or other single-column results, we can directly through this set of convenient template methods to query:
int age = Jdbctemplate.queryforint ("Select age from Customer where customerid=?", New Object[]{new Integer (100)});
...
Long interval = Jdbctemplate.queryforlong ("SELECT count (customerId) from customer");
...
String customerName = jdbctemplate.queryforstring ("Select username from customer where customerid=110");
...
Map Singlecustomer = Jdbctemplate.queryformap ("SELECT * FROM Customer Limit 1");
...
The queryForMap method differs from other methods in that its query results are returned in JAVA.UTIL.MAP form, the map key corresponds to the column name of the queried table, and the map value is of course the value of the column corresponding to the key. Of course, as you can see, this set of template methods is primarily used for single-result queries, and when used, make sure that your SQL queries return a single result, otherwise, JdbcTemplate throws an Org.springframework.dao.IncorrectResultSizeDataAccessException exception.
If the results of the query return multiple rows, and you don't care if they have a strong type constraint, the following template methods can help you:
List queryforlist (String sql)
List queryforlist (String sql, object[] args)
The queryForList method executes the query based on the SQL passed in and the corresponding parameters. The results of the query are returned as java.util.List, and each element in the returned java.util.List is a java.util.Map type, corresponding to one row in the result set, and the map key is the column name for each column, and the value of map is the value corresponding to the current row name.
Well, if these are not enough to meet your query needs, then we will go further and use the corresponding callback interface to customize the return of the query results!
There are three main callback interface definitions for queries:
Org.springframework.jdbc.core.ResultSetExtractor. Basically belongs to the callback interface used internally by JdbcTemplate, compared to the following two callback interfaces, ResultSetExtractor has more control, because using it, you need to handle the resultset yourself:
public interface ResultSetExtractor
{
Object Extractdata (ResultSet rs) throws SQLException, DataAccessException;
}
After you have processed the resultset directly, you can wrap the processed results back in any form you want.
Org.springframework.jdbc.core.RowCallbackHandler. RowCallbackHandler with respect to ResultSetExtractor, only focusing on the processing of single-row results, The processed results can be stored as needed in the current RowCallbackHandler object or in the context of the program using JdbcTemplate, of course, this is entirely a personal hobby. RowCallbackHandler is defined as follows:
public interface RowCallbackHandler
{
void Processrow (ResultSet rs) throws SQLException;
}
The lite version of Org.springframework.jdbc.core.RowMapper. ResultSetExtractor, which functions like RowCallbackHandler and focuses only on the results of processing a single line, however, The processed results are combined by the ResultSetExtractor implementation class. The RowMapper interface is defined as follows:
public interface RowMapper
{
Object Maprow (ResultSet rs, int rowNum) throws SQLException;
}
To illustrate the difference between the use of these three callback interfaces and the other, we set the following scenario:
A database table has multiple lines of information in customer, and after querying the table, we need to map the customer information for each row to the domain object customer and return all query results as java.util.List.
Now, we use these three callback interfaces to query the Customer table:
List customerlist = (list) jdbctemplate.query ("SELECT * from Customer", new ResultSetExtractor () {
Public Object Extractdata (ResultSet rs) throws Sqlexception,dataaccessexception
{
List customers = new ArrayList ();
while (Rs.next ())
{
Customer customer = new Customer ();
Customer.setfirstname (rs.getstring (1));
Customer.setlastname (rs.getstring (2));
...
Customers.add (customer);
}
return customers;
}});
List customerlist = Jdbctemplate.query ("SELECT * from Customer", new RowMapper () {
Public Object Maprow (ResultSet rs, int rowNumber) throws SQLException {
Customer customer = new Customer ();
Customer.setfirstname (rs.getstring (1));
Customer.setlastname (rs.getstring (2));
...
return customer;
}});
Final List customerlist = new ArrayList ();
Jdbctemplate.query ("SELECT * from Customer", new RowCallbackHandler () {
public void Processrow (ResultSet rs) throws SQLException {
Customer customer = new Customer ();
Customer.setfirstname (rs.getstring (1));
Customer.setlastname (rs.getstring (2));
...
customerList.Add (customer);
}});
If you do not find the biggest difference in where, then let me fine table:
The return value of the query method that uses three callback interfaces as parameters is different:
The query method with ResultSetExtractor as the method parameter returns the object type result, and we need to make a forced transformation to use the result.
The query method using the RowMapper interface as the method parameter directly returns the result of the list type;
The Query method takes RowCallbackHandler as the method parameter, and the return value is void;
Using ResultSetExtractor as the callback interface to process query results, we need to declare the collection class ourselves, traverse the resultset ourselves, assemble the customer object based on each row of data, and add the assembled customer object to the collection class. , the method is ultimately only responsible for returning the assembled set;
Using RowMapper is more convenient than direct use of resultsetextractor, only responsible for processing single-row results, now, we just have to assemble the results of a single row back on the line, the rest of the work, all is jdbctemplate internal things. In fact, Jdbctemplae will use a ResultSetExtractor implementation class to do the rest of the work, after all, the work to be done is still someone to do it?!
This ResultSetExtractor implementation class used internally by Jdbctemplae is Org.springframework.jdbc.core.RowMapperResultSetExtractor, It holds a reference to an RowMapper instance internally, and when the result set is processed, the processing of the single row of data is delegated to the RowMapper instance it holds, while the rest is responsible for:
Public Object Extractdata (ResultSet rs) throws SQLException {
List results = (this.rowsexpected > 0? new ArrayList (this.rowsexpected): New ArrayList ());
int rowNum = 0;
while (Rs.next ()) {
Results.add (This.rowMapper.mapRow (RS, rownum++));
}
return results;
}
This should be clear why RowMapper to deal with a single result can be completed resultsetextractor quite a lot of work, right?!
RowCallbackHandler while working with RowMapper is a single row of data, but in addition to dealing with single-line results, it is responsible for the final result of the Assembly and acquisition work, where we are using the current context declaration of the list to obtain the final query results, however, We can also declare a RowCallbackHandler implementation class in which the corresponding collection class is declared, so that we can obtain the final query result from the RowCallbackHandler implementation class:
public class Genericrowcallbackhandler implements RowCallbackHandler {
Private List collections = new ArrayList ();
public void Processrow (ResultSet rs) throws SQLException {
Customer customer = new Customer ();
Customer.setfirstname (rs.getstring (1));
Customer.setlastname (rs.getstring (2));
...
Collections.add (customer);
}
Public List GetResults ()
{
return collections;
}
}
Genericrowcallbackhandler handler = new Genericrowcallbackhandler ();
Jdbctemplate.query ("SELECT * from Customer", Handler ());
List customerlist = Handler.getresults ();
The usage is clear, but Genericrowcallbackhandler is poorly reused.
RowCallbackHandler because is also processing a single row of data, so, someone has to do the Traverse resultset work, this person is actually a ResultSetExtractor implementation class, it is jdbctemplate an internal static class, Named Rowcallbackhandlerresultsetextractor, a look at its definition you know where the mystery lies:
private static class Rowcallbackhandlerresultsetextractor implements ResultSetExtractor {
Private final RowCallbackHandler rch;
Public Rowcallbackhandlerresultsetextractor (RowCallbackHandler rch) {
This.rch = RCH;
}
Public Object Extractdata (ResultSet rs) throws SQLException {
while (Rs.next ()) {
This.rch.processRow (RS);
}
return null;
}
}
Overall, the internal work is ultimately done by ResultSetExtractor, RowCallbackHandler and RowMapper just to help us simplify the use of the operation. Therefore, in practice, RowCallbackHandler and RowMapper are our most commonly used choices.
For queries using JdbcTemplate, this is basically the case, and of course, if you want to use a lower-level Execute method based on Statementcallback, it's your personal decision. However, to know more information about query-related template methods in JdbcTemplate, in the actual use of reference JdbcTemplate Javadoc can, of course, the IDE is more convenient.
JdbcTemplate query data The difference between three kinds of callback