Java 编程 - Spring 和 JDBCTemplate - 使用 query、queryForList 或 queryForRowSet?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1660756/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Java Programming - Spring and JDBCTemplate - Use query, queryForList or queryForRowSet?
提问by Adrian
My Java (JDK6) project uses Springand JDBCTemplatefor all its database access. We recently upgraded from Spring 2.5 to Spring 3 (RC1). The project does not use an ORM like Hibernatenor EJB.
我的 Java (JDK6) 项目使用Spring和JDBCTemplate进行所有数据库访问。我们最近从 Spring 2.5 升级到 Spring 3 (RC1)。该项目不使用像Hibernate或EJB这样的 ORM 。
If I need to read a bunch of records, and do some internal processing with them, it seems like there are several (overloaded) methods: query, queryForList and queryForRowSet
如果我需要读取一堆记录,并对它们进行一些内部处理,似乎有几种(重载)方法:query、queryForList 和 queryForRowSet
What should be the criteria to use one instead of the other? Are there any performance differences? Best practices?
使用一个而不是另一个的标准应该是什么?是否有任何性能差异?最佳实践?
Can you recommend some external references for further research on this topic?
您能否推荐一些外部参考资料以进一步研究该主题?
采纳答案by Jason Gritman
I find that the standard way to access as list is via the query()
methods rather than any of the other approaches. The main difference between query
and the other methods is that you'll have to implement one of the callback interfaces (either RowMapper
, RowCallbackHandler
, or ResultSetExtractor
) to handle your result set.
我发现作为列表访问的标准方法是通过query()
方法而不是任何其他方法。之间的主要区别query
与其他的方法是,你必须实现回调接口中的一个(或RowMapper
,RowCallbackHandler
或ResultSetExtractor
)来处理结果集。
A RowMapper
is likely what you'll find yourself using most of the time. It's used when each row of the result set corresponds to one object in your list. You only have to implement a single method mapRow
where you populate the type of object that goes in your row and return it. Spring also has a BeanPropertyRowMapper
which can populate the objects in a list via matching the bean property names to the column names (NB this class is for convenience not performance).
ARowMapper
很可能是您发现自己大部分时间都在使用的。当结果集的每一行对应于列表中的一个对象时使用它。您只需要实现一个方法mapRow
,在其中填充行中的对象类型并返回它。Spring 也有一个BeanPropertyRowMapper
可以通过将 bean 属性名称与列名称匹配来填充列表中的对象(注意这个类是为了方便而不是性能)。
A RowCallbackHandler
is more useful when you need your results to be more than just a simple list. You'll have to manage the return object yourself you are using this approach. I usually find myself using this when I need a map structure as my return type (i.e. for grouped data for a tree table or if I'm creating a custom cache based of the primary key).
RowCallbackHandler
当您需要的结果不仅仅是一个简单的列表时,A更有用。您必须自己管理使用这种方法的返回对象。当我需要一个地图结构作为我的返回类型(即用于树表的分组数据或者如果我正在创建基于主键的自定义缓存)时,我通常会发现自己使用它。
A ResultSetExtractor
is used when you want to control the iteration of the results. You implment a single method extractData
that will be the return value of the call to query
. I only find myself using this if I have to build some custom data structure that is more complex to build using either of the other callback interfaces.
ResultSetExtractor
当您想要控制结果的迭代时使用A。您实现了一个方法extractData
,该方法将作为对 的调用的返回值query
。如果我必须构建一些使用其他回调接口构建更复杂的自定义数据结构,我只会发现自己使用它。
The queryForList()
methods are valuable in that you don't have to implement these callback methods. There are two ways use queryForList. The first is if you're only querying a single column from the database (for example a list of strings) you can use the versions of the method that takes a Class as an argument to automatically give you a list of only objects of those classes.
这些queryForList()
方法的价值在于您不必实现这些回调方法。有两种使用 queryForList 的方法。第一个是如果您只查询数据库中的单个列(例如字符串列表),您可以使用将 Class 作为参数的方法的版本自动为您提供这些类的唯一对象列表.
When calling the other implementations of queryForList()
you'll get a list back with each entry being a map of for each column. While this is nice in that you are saved the expense of writing the callback methods, dealing with this data structure is quite unwieldy. You'll find yourself doing a lot of casting since the map's values are of type Object
.
调用其他实现时,queryForList()
您将获得一个列表,其中每个条目都是每列的映射。虽然这很好,因为您可以节省编写回调方法的费用,但处理这种数据结构非常笨拙。您会发现自己进行了大量转换,因为地图的值是 类型Object
。
I've actually never seen the queryForRowSet
methods used in the wild. This will load the entire result of the query into a CachedRowSet
object wapped by a Spring SqlRowSet. I see a big downside in using this object in that if you're passing the SqlRowSet
around to the other layers of your application, you're coupling those layers to your data access implementation.
我实际上从未见过queryForRowSet
在野外使用的方法。这会将查询的整个结果加载到CachedRowSet
由 Spring SqlRowSet转换的对象中。我看到使用这个对象的一个很大的缺点是,如果你将SqlRowSet
周围传递到应用程序的其他层,你会将这些层耦合到你的数据访问实现。
You shouldn't see any huge performance differences between any of these calls except as I mentioned with the BeanPropertyRowMapper
. If you're working with some complex manipulation of a large result set, you might be able to get some performance gains from writing an optimized ResultSetExtractor
for your specific case.
除了我在BeanPropertyRowMapper
. 如果您正在处理大型结果集的一些复杂操作,您可能能够通过ResultSetExtractor
为您的特定情况编写优化来获得一些性能提升。
If you want to learn more I would consult the Spring JDBC documentationand the JavaDoc for the classes I've mentioned. You can also take a look at some of the books on the Spring Framework. Though it's a bit dated Java Development with the Spring Frameworkhas a very good section on working with the JDBC framework. Most of all, I would say just try writing some code with each method and see what works best for you.
如果您想了解更多信息,我会查阅Spring JDBC 文档和JavaDoc 以了解我提到的类。您还可以查看一些有关 Spring Framework 的书籍。虽然它有点过时了Java Development with the Spring Framework有一个关于使用 JDBC 框架的非常好的部分。最重要的是,我会说只是尝试使用每种方法编写一些代码,看看哪种方法最适合您。
回答by Esko
Since you are in the wonderful Generics land, what you may really want to do is to use SimpleJdbcTemplate
and use its query()
methods for Lists
of objects and queryForObject()
for individual objects. Reasoning for this simply is that they're even easier to use than the ones in JdbcTemplate
.
既然你在美妙的泛型领域,你可能真正想做的是使用SimpleJdbcTemplate
和使用它的query()
方法 forLists
对象和queryForObject()
单个对象。这样做的原因很简单,因为它们比JdbcTemplate
.
回答by todd.pierzina
One small addition to the excellent answers above: additional methods, like queryForInt, queryForLong, queryForMap, queryForObject, etc. might seem like good options at times if you're running a simple query and expect a single row.
对上述优秀答案的一小部分补充:附加方法,如 queryForInt、queryForLong、queryForMap、queryForObject 等,如果您正在运行一个简单的查询并期望单行,有时可能看起来是不错的选择。
However, if you could get 0 or 1 rows back, the queryForList method is generally easier, otherwise you'd have to catch IncorrectResultSizeDataAccessException. I learned that the hard way.
但是,如果您可以返回 0 或 1 行,则 queryForList 方法通常更容易,否则您必须捕获 IncorrectResultSizeDataAccessException。我学会了艰难的方式。