Java Programming - Spring 和 JDBCTemplate - 使用 query,queryForList 或 queryForRowSet?

2022-09-02 23:02:28

我的Java(JDK6)项目使用SpringJDBCTemplate进行所有数据库访问。我们最近从 Spring 2.5 升级到 Spring 3 (RC1)。该项目不使用像HibernateEJB这样的ORM。

如果我需要读取一堆记录,并用它们进行一些内部处理,似乎有几种(重载的)方法:query,queryForList和queryForRowSet。

使用一个而不是另一个的标准应该是什么?是否存在任何性能差异?最佳实践?

您能推荐一些外部参考资料来进一步研究这个主题吗?


答案 1

我发现访问列表的标准方法是通过方法而不是任何其他方法。与其他方法之间的主要区别在于,您必须实现其中一个回调接口(、 、 或 )来处理结果集。query()queryRowMapperRowCallbackHandlerResultSetExtractor

A可能是你发现自己大部分时间都在使用的。当结果集的每一行对应于列表中的一个对象时,将使用它。您只需实现一个方法,您可以在其中填充行中对象的类型并返回它。Spring还有一个,可以通过将bean属性名称与列名称匹配来填充列表中的对象(注意,这个类是为了方便而不是性能)。RowMappermapRowBeanPropertyRowMapper

当您需要结果不仅仅是一个简单的列表时,A 更有用。您必须自己管理使用此方法的返回对象。当我需要映射结构作为我的返回类型时(即,对于树表的分组数据,或者我正在创建基于主键的自定义缓存),我通常会发现自己使用它。RowCallbackHandler

当您想要控制结果的迭代时,将使用 A。您引入了一个方法,该方法将成为对 的调用的返回值。只有当我必须构建一些自定义数据结构时,我才会发现自己使用它,这些结构使用其他任何一个回调接口构建起来都更复杂。ResultSetExtractorextractDataquery

这些方法的价值在于您不必实现这些回调方法。有两种方法可以使用 queryForList。第一种是,如果仅从数据库中查询单个列(例如字符串列表),则可以使用将 Class 作为参数的方法版本,以自动为您提供仅包含这些类的对象的列表。queryForList()

调用 的其他实现时,您将获得一个列表,其中每个条目都是每列的映射。虽然这很好,因为您可以节省编写回调方法的费用,但处理此数据结构非常笨拙。您会发现自己做了很多转换,因为地图的值是 类型 。queryForList()Object

实际上,我从未见过野外使用的方法。这会将查询的整个结果加载到由 Spring SqlRowSet 擦除的对象中。我看到使用此对象的一大缺点是,如果您要将这些层传递给应用程序的其他层,则会将这些层耦合到数据访问实现。queryForRowSetCachedRowSetSqlRowSet

您不应该看到这些调用之间的任何巨大性能差异,除非我在 .如果您正在处理大型结果集的一些复杂操作,则可以通过编写针对您的特定情况进行优化的结果集来获得一些性能提升。BeanPropertyRowMapperResultSetExtractor

如果你想了解更多,我会参考Spring JDBC文档JavaDoc来了解我提到的类。你也可以看看一些关于Spring Framework的书。虽然它有点过时,但使用Spring Framework的Java开发有一个非常好的部分来使用JDBC框架。最重要的是,我想说的是,只需尝试使用每种方法编写一些代码,看看哪种方法最适合您。


答案 2

由于您处于奇妙的泛型领域,您可能真正想做的是使用SimpleJdbcTemplate并将其方法用于对象和单个对象。这样做的原因很简单,它们比 中的那些更容易使用。query()ListsqueryForObject()JdbcTemplate


推荐