简体   繁体   English

RETURN_GENERATED_KEYS与指定生成的列名称之间的区别

[英]Difference between RETURN_GENERATED_KEYS and specifying the generated column names

What is the difference between the prepareStatement(String sql, int autoGeneratedKeys) and prepareStatement(String sql, String[] columnNames ) methods of the JDBC Connection class? JDBC Connection类的prepareStatement(String sql, int autoGeneratedKeys)prepareStatement(String sql, String[] columnNames方法有什么区别?

The Javadoc for both indicates that the returned PreparedStatement object is capable of returning auto-generated keys if the SQL statement is an INSERT statement. 两者的Javadoc表示如果SQL语句是INSERT语句,则返回的PreparedStatement对象能够返回自动生成的键。 In the case of the first API, Statement.RETURN_GENERATED_KEYS needs to be passed for the autoGeneratedKeys parameter. 对于第一个API,需要为autoGeneratedKeys参数传递Statement.RETURN_GENERATED_KEYS In the case of the second API, the names of generated columns are passed as a string array. 对于第二个API,生成列的名称将作为字符串数组传递。

What are the reasons for using one over the other? 使用其中一个的原因是什么?

I noticed that Spring's SimpleJdbcInsert class prefers the variant where the column names are specified: AbstractJdbcInsert.prepareStatementForGeneratedKeys 我注意到Spring的SimpleJdbcInsert类更喜欢指定列名的变体: AbstractJdbcInsert.prepareStatementForGeneratedKeys

Why is that? 这是为什么?

The reasons are convenience, flexibility, performance and compatibility. 原因是方便性,灵活性,性能和兼容性。 For example, some database cannot know which columns are auto-generated or not, so by default their drivers return all columns when using Statement.RETURN_GENERATED_KEYS . 例如,某些数据库无法知道哪些列是自动生成的,因此默认情况下,当使用Statement.RETURN_GENERATED_KEYS时,它们的驱动程序将返回所有列。

This can have impact on performance because: 这会对性能产生影响,因为:

  1. All those values need to be transferred from database to client, 所有这些值都需要从数据库传输到客户端,
  2. On some databases this requires a query on the metadata to know which columns to fetch. 在某些数据库上,这需要查询元数据以了解要获取的列。

For example, the driver for PostgreSQL will append RETURNING * (so it only has point 1 to worry about), while the Firebird driver (which I maintain) also has to query the metadata. 例如,PostgreSQL的驱动程序将附加RETURNING * (因此它只需要担心点1),而Firebird驱动程序(我维护)也必须查询元数据。

Some database drivers by default return a column that is not directly useful (eg Oracle - used to? - return the ROWID , which means you have to query the actual field yourself), and some databases return only the primary key, while there might also be other generated fields, and I believe that some database drivers return the last generated key, even if the table doesn't use an identity field(!). 默认情况下,某些数据库驱动程序返回一个不直接有用的列(例如Oracle - 用于? - 返回ROWID ,这意味着您必须自己查询实际字段),而某些数据库只返回主键,而有些数据库也可能返回是其他生成的字段,我相信一些数据库驱动程序返回最后生成的密钥,即使该表不使用标识字段(!)。

The methods prepareStatement(String sql, String[] columnNames) and prepareStatement(String sql, int[] columnIndexes) give more control (if supported), about what is returned. 方法prepareStatement(String sql, String[] columnNames)prepareStatement(String sql, int[] columnIndexes)给出更多控件(如果支持),关于返回的内容。 If you know exactly which fields you need or want, you can specify them and get exactly those fields, without having to worry about the differences in behavior that you get with RETURN_GENERATED_KEYS . 如果您确切地知道您需要或想要哪些字段,您可以指定它们并准确获取这些字段,而不必担心使用RETURN_GENERATED_KEYS获得的行为差异。

Depending on the implementation, the one taking String[] columnNames is probably most efficient as the names can simply be put in verbatim, while the int[] columnIndexes might still require a metadata query the get the actual names. 取决于实现,使用String[] columnNames那个可能是最有效的,因为名称可以简单地逐字放置,而int[] columnIndexes可能仍然需要元数据查询获取实际名称。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM