Spring JdbcTemplate 的 query() 方法的实现到底是如何工作的?

How exactly works this implementation of the query() method of the Spring JdbcTemplate?

我正在开发一个 Spring 应用程序,该应用程序使用 JdbcTemplate 来查询数据库,但我对它的工作原理有一些疑问。

所以,进入服务 class,我有这个执行查询的方法定义:

//JDBC TEMPLATE SELECT EXAMPLE 
public List<DBLog> queryAllLogs() {
    System.out.println("JDBCExample: queryAllLogs() is called");    

    final String QUERY_SQL = "SELECT * FROM LOG ORDER BY IDLOG";

    List<DBLog> dbLogList = this.jdbcTemplate.query(QUERY_SQL, new RowMapper<DBLog>() {

        public DBLog mapRow(ResultSet resulSet, int rowNum) throws SQLException {
            System.out.println("Getting log: "+ rowNum + " content: " + resulSet.getString("LOGSTRING"));

            DBLog dbLog = new DBLog();
            dbLog.setIDLOG(resulSet.getInt("IDLOG"));
            dbLog.setLOGSTRING(resulSet.getString("LOGSTRING"));
            return dbLog;
        }
    });
    return dbLogList; 
}

此方法简单地执行一个查询,即 return LOG table 内的所有记录按 IDLOG 字段值排序。这很容易理解。

阅读官方文档后,我发现 query() 方法的实现需要 2 个对象:查询字符串和一个 RowMapper 对象,以及:

Query using a prepared statement, mapping each row to a Java object via a RowMapper

所以我认为 QUERY_SQL 查询字符串被 query() 方法实现自动转换为 PreparedStatment(是正确的还是我遗漏了什么?)

我完全不清楚的是,在我看来,在前面的示例中,我将 RowMapper 实现定义为查询方法的第二个参数。

所以这个特定的实现包含 mapRow(ResultSet resulSet, int rowNum) 方法实现,据我所知,该方法实现是为 ResultSet 对象的每一行调用的 return 查询执行。因此,此方法将自动映射 DBLog 上的特定行,该行将自动添加到 returned List<DBLog> dbLogList 列表中。

是我的推理正确还是我遗漏了什么?

谁做这些工作?是这个特定的 query() 方法实现(采用这两个特定输入参数的那个)注意调用传递的 RowMapper 对象的 mapRow() 方法然后添加 return将 DBLog 对象添加到列表中?

你的推理完全正确。

首先,看一下this table in the documentation。它列出了 Spring JDBC 自动执行的所有操作以及您需要执行的操作。基本上,使用 Spring JDBC 时你需要做的就是:

  • 设置 JDBC 连接
  • 指定要执行的SQL语句
  • 如果有参数,请提供参数值
  • 对于每个结果,执行将结果转换为对象的工作

JDBCTemplate.query(String, RowMapper) 遵循相同的模式。首先,你给它一个 SQL 语句来执行:这是第一个参数(上面列表的第 2 点)。其次,你给它一个对象,负责将每个结果转换成你的域对象(上面列表的第 4 点)。

此对象称为 RowMapper,因为它 将数据库的 行(由 ResultSet 对象表示)映射到您的域对象中。

这是使用 Spring JDBC 优于原始 JDBC 的主要优势之一:它将所有常见和重复的任务分解为核心。是的,它将在引擎盖下使用 PreparedStatement,它将被执行并且 ResultSet 将被循环。并且在此循环的每次迭代中(由 Spring JDBC 生成),您的 RowMapper 将被调用。它的结果会被SpringJDBC聚合成一个List最后返回。