prepareStatement(String sql, int autoGeneratedKeys)
之间有什么区别?和 prepareStatement(String sql, String[] columnNames
) JDBC Connection
类的方法?
两者的 Javadoc 表明如果 SQL 语句是 INSERT
语句,则返回的 PreparedStatement
对象能够返回自动生成的键。对于第一个 API,需要为 autoGeneratedKeys
参数传递 Statement.RETURN_GENERATED_KEYS
。对于第二个 API,生成的列的名称作为字符串数组传递。
使用一个而不是另一个的原因是什么?
我注意到 Spring 的 SimpleJdbcInsert
类更喜欢指定列名的变体:AbstractJdbcInsert.prepareStatementForGeneratedKeys
这是为什么?
最佳答案
原因是方便、灵活、性能和兼容性。例如,某些数据库不知道哪些列是自动生成的,哪些列不是,因此默认情况下,它们的驱动程序在使用 Statement.RETURN_GENERATED_KEYS
时返回所有 列。
这会对性能产生影响,因为:
- 所有这些值都需要从数据库传输到客户端,
- 在某些数据库中,这需要查询元数据以了解要获取的列。
例如,PostgreSQL 的驱动程序将附加 RETURNING *
(因此它只需要担心第 1 点),而 Firebird 驱动程序(我维护的)也必须查询元数据。
某些数据库驱动程序默认返回一个不直接有用的列(例如 Oracle - 曾经? - 返回 ROWID
,这意味着您必须自己查询实际字段),而一些数据库仅返回主键,同时可能还有其他生成的字段,我相信某些数据库驱动程序会返回最后生成的键,即使表不使用标识字段(!)。
方法 prepareStatement(String sql, String[] columnNames)
和 prepareStatement(String sql, int[] columnIndexes)
对返回的内容给予更多控制(如果支持)。如果您确切知道需要或想要哪些字段,则可以指定它们并准确获取这些字段,而不必担心使用 RETURN_GENERATED_KEYS
时出现的行为差异。
根据实现方式,采用 String[] columnNames
的方法可能最有效,因为名称可以简单地逐字输入,而 int[] columnIndexes
可能最有效仍然需要元数据查询来获取实际名称。
关于java - RETURN_GENERATED_KEYS 和指定生成的列名的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30552299/