RETURN_GENERATED_KEYS 和指定生成的列名的区别
Difference between RETURN_GENERATED_KEYS and specifying the generated column names
JDBCConnection
class的prepareStatement(String sql, int autoGeneratedKeys)
and prepareStatement(String sql, String[] columnNames
)方法有什么区别?
两者的 Javadoc 表明如果 SQL 语句是 INSERT
语句,则返回的 PreparedStatement
对象能够返回自动生成的键。在第一个API的情况下,autoGeneratedKeys
参数需要传递Statement.RETURN_GENERATED_KEYS
。在第二个 API 的情况下,生成的列的名称作为字符串数组传递。
使用其中一个的原因是什么?
我注意到 Spring 的 SimpleJdbcInsert
class prefers the variant where the column names are specified: AbstractJdbcInsert.prepareStatementForGeneratedKeys
这是为什么?
原因是方便、灵活、性能和兼容性。例如,某些数据库无法知道哪些列是自动生成的或不是,因此默认情况下它们的驱动程序 return all 列在使用 Statement.RETURN_GENERATED_KEYS
时。
这会对性能产生影响,因为:
- 所有这些值都需要从数据库传输到客户端,
- 在某些数据库上,这需要查询元数据才能知道要获取哪些列。
例如,PostgreSQL 的驱动程序将附加 RETURNING *
(因此它只有第 1 点需要担心),而 Firebird 驱动程序(我维护的)也必须查询元数据。
一些数据库驱动默认return一个不能直接使用的列(例如Oracle - 曾经? - return ROWID
,这意味着你必须查询实际字段自己),有些数据库 return 只有主键,同时可能还有其他生成的字段,我相信有些数据库驱动程序 return 最后生成的键,即使 table 不使用身份字段 (!)。
方法 prepareStatement(String sql, String[] columnNames)
and prepareStatement(String sql, int[] columnIndexes)
提供更多控制(如果支持),关于 return 编辑的内容。如果您确切知道需要或想要哪些字段,则可以指定它们并准确获取这些字段,而不必担心使用 RETURN_GENERATED_KEYS
.
时的行为差异
根据实施方式,采用 String[] columnNames
的方法可能最有效,因为名称可以简单地逐字输入,而 int[] columnIndexes
可能仍需要元数据查询才能获取实际名称.
JDBCConnection
class的prepareStatement(String sql, int autoGeneratedKeys)
and prepareStatement(String sql, String[] columnNames
)方法有什么区别?
两者的 Javadoc 表明如果 SQL 语句是 INSERT
语句,则返回的 PreparedStatement
对象能够返回自动生成的键。在第一个API的情况下,autoGeneratedKeys
参数需要传递Statement.RETURN_GENERATED_KEYS
。在第二个 API 的情况下,生成的列的名称作为字符串数组传递。
使用其中一个的原因是什么?
我注意到 Spring 的 SimpleJdbcInsert
class prefers the variant where the column names are specified: AbstractJdbcInsert.prepareStatementForGeneratedKeys
这是为什么?
原因是方便、灵活、性能和兼容性。例如,某些数据库无法知道哪些列是自动生成的或不是,因此默认情况下它们的驱动程序 return all 列在使用 Statement.RETURN_GENERATED_KEYS
时。
这会对性能产生影响,因为:
- 所有这些值都需要从数据库传输到客户端,
- 在某些数据库上,这需要查询元数据才能知道要获取哪些列。
例如,PostgreSQL 的驱动程序将附加 RETURNING *
(因此它只有第 1 点需要担心),而 Firebird 驱动程序(我维护的)也必须查询元数据。
一些数据库驱动默认return一个不能直接使用的列(例如Oracle - 曾经? - return ROWID
,这意味着你必须查询实际字段自己),有些数据库 return 只有主键,同时可能还有其他生成的字段,我相信有些数据库驱动程序 return 最后生成的键,即使 table 不使用身份字段 (!)。
方法 prepareStatement(String sql, String[] columnNames)
and prepareStatement(String sql, int[] columnIndexes)
提供更多控制(如果支持),关于 return 编辑的内容。如果您确切知道需要或想要哪些字段,则可以指定它们并准确获取这些字段,而不必担心使用 RETURN_GENERATED_KEYS
.
根据实施方式,采用 String[] columnNames
的方法可能最有效,因为名称可以简单地逐字输入,而 int[] columnIndexes
可能仍需要元数据查询才能获取实际名称.