【问题标题】:How exactly works this implementation of the query() method of the Spring JdbcTemplate?Spring JdbcTemplate 的 query() 方法的这种实现究竟是如何工作的?
【发布时间】:2015-11-29 20:04:40
【问题描述】:

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

所以,在一个服务类中,我有这个执行查询的方法定义:

//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; 
}

此方法只执行一个查询,返回由IDLOG 字段值排序的LOG 表中的所有记录。这很容易理解。

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

使用准备好的语句进行查询,将每一行映射到一个 Java 对象 通过 RowMapper

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

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

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

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

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

【问题讨论】:

    标签: java spring spring-mvc spring-jdbc jdbctemplate


    【解决方案1】:

    你的推理完全正确。

    首先,看看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 将被调用。它的结果会被Spring JDBC聚合成一个List,最后返回。

    【讨论】:

    • 好的,tnx 现在很清楚了。只有一个疑问:我可以使用 Spring JdbcTemplate 以某种方式直接对 ResultSet 进行操作吗?
    • @AndreaNobili 操作如何?有一个 query 方法可以为您提供完整的 ResultSet 供您使用 ResultSetExtractor 进行循环,但我不确定您的意思。
    • 我的意思是你指定的,再次 tnx :-)
    猜你喜欢
    • 1970-01-01
    • 2015-06-26
    • 2015-12-02
    • 2019-01-05
    • 2015-04-23
    • 1970-01-01
    • 2015-02-19
    • 2013-12-05
    • 2020-07-05
    相关资源
    最近更新 更多