使用Spring JdbcTemplate进行多个数据库操作

5

我喜欢JdbcTemplate的明显简洁性,但对它的工作方式有些困惑。似乎每个操作(query()或update())都会从数据源中获取连接并关闭。

这很好,但如何在同一连接中执行多个SQL查询呢?

我可能希望按顺序执行多个操作(例如SELECT后跟INSERT再跟一个commit),或者我可能希望执行嵌套查询(基于每行结果执行SELECT,然后执行第二个SELECT)。

我该如何使用JdbcTemplate来实现这些功能?我是否正在使用正确的类?

2个回答

9

如何在同一连接中执行多个 SQL 查询?

正确的答案是 "使用事务"。如果您开始了事务,然后使用 JdbcTemplate 执行多个操作,则每个操作都在事务范围内,因此保证使用相同的连接。

如果您不想涉及事务,则可以使用更原始的 JdbcTemplate 操作,例如 execute(ConnectionCallback action),其中您提供一个 ConnectionCallback 实例,该实例获得一个 Connection,您可以在其上执行任何选择的操作。当然,这样做时,您将无法在任何实际操作中获得 JdbcTemplate 的帮助。

在 Spring 中,事务真的很容易,您应该考虑使用它们(请参见上面的链接)。


实际上,您不需要使用实际事务来使用相同的连接。但是,就像在Spring中使用事务一样,需要使用TransactionProxyFactoryBean或Transaction Template。您可以使用PROPAGATION_SUPPORTS或PROPAGATION_NEVER进行传播,并且它将重用相同的连接,但不会启动真正的事务。 - Bill Poitras
1
如果您正在使用连接池,不需要担心在语句之间未获取相同的连接吗? - It Grunt

5
我假设您需要事务处理?如果是这样,请查看Spring,JdbcTemplate和Transactions
顺便说一句,我建议您再看看Ibatis。Spring JDBC似乎很方便,但它有一个主要问题:将结果集映射到对象的默认映射使用Spring类,实际上在处理大型结果集时非常慢。您可以通过为这些查询编写自己的行映射器来解决此问题,但就个人而言,我不想编写此类样板代码。
举个例子,我有一个查询使用基于Spring反射的行映射器花费了50秒,而使用手动编码的行映射器只需2秒。
另外,Spring JDBC使用内联SQL。在Java中,这相当丑陋,因为Java(令人恼火地)没有很好的多行字符串格式。

“结果集到对象的默认映射使用Spring类”,您能详细说明一下吗?我总是使用RowMappers来查询对象。还有其他选项吗? - matt b
我也很好奇这里的“默认映射”是什么意思,以及他们如何使用反射。我认为RowMappers是JdbcTemplate的核心。 - spaaarky21
@mattb,@spaaarky21 Spring可以将结果集映射到对象中,例如使用BeanPropertyRowMapper类(您可以通过谷歌搜索使用它的示例)。简单查询如下:List<MyOrder> orders = jt.query("SELECT * FROM orders WHERE custId=?", new BeanPropertyRowMapper<MyOrders>(MyOrder.class), id); 然后您就不必包装RowMapper<T>的实现,而是将字段映射到MyOrder类的setter中。 - Dimitry K

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接