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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 18:48:04  来源:igfitidea点击:

Java Programming - Spring and JDBCTemplate - Use query, queryForList or queryForRowSet?

javaspringrecordsetjdbctemplate

提问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) 项目使用SpringJDBCTemplate进行所有数据库访问。我们最近从 Spring 2.5 升级到 Spring 3 (RC1)。该项目不使用像HibernateEJB这样的 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 queryand 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与其他的方法是,你必须实现回调接口中的一个(或RowMapperRowCallbackHandlerResultSetExtractor)来处理结果集。

A RowMapperis 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 mapRowwhere you populate the type of object that goes in your row and return it. Spring also has a BeanPropertyRowMapperwhich 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 RowCallbackHandleris 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 ResultSetExtractoris used when you want to control the iteration of the results. You implment a single method extractDatathat 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 queryForRowSetmethods used in the wild. This will load the entire result of the query into a CachedRowSetobject wapped by a Spring SqlRowSet. I see a big downside in using this object in that if you're passing the SqlRowSetaround 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 ResultSetExtractorfor 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 SimpleJdbcTemplateand use its query()methods for Listsof 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。我学会了艰难的方式。