[英]Return Timestamp With Prepared Statement
我有一个自动生成的时间戳,每次在mysql表中插入或更新一条记录时都会创建该时间戳。 有没有一种方法可以类似于使用密钥持有者返回新创建的id的方式返回此时间戳?
KeyHolder keyHolder = new GeneratedKeyHolder();
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
//Insert Contact
jdbcTemplate.update(new PreparedStatementCreator() {
@Override
public PreparedStatement createPreparedStatement(Connection connection) throws SQLException {
PreparedStatement preparedStatement = connection.prepareStatement(SQL_ADD, Statement.RETURN_GENERATED_KEYS);
preparedStatement.setString(1, contact.getFirstName());
preparedStatement.setString(2, contact.getLastName());
preparedStatement.setInt(3, contact.getOrganizationId());
preparedStatement.setString(4, contact.getType());
preparedStatement.setInt(5, contact.getUserId());
return preparedStatement;
}
}, keyHolder);
//Use keyholder to obtain newly created id
contact.setId(keyHolder.getKey().intValue());
是否有某种方法也可以返回新的时间戳而不必重新查询表? 我一直在寻找将ID与ID一起作为密钥返回给密钥持有者的方法,但是它似乎没有作为密钥返回吗?
不太令人满意,但我认为“否”是您问题的答案。 我不了解Spring的任何内容,但是我认为这是由于包装了基本的JDBC。 请参阅http://docs.oracle.com/javase/6/docs/api/java/sql/Statement.html#getGeneratedKeys%28%29
您唯一的选择是在MySQL上创建一个具有out参数的存储过程,然后调用该存储过程。 参见http://dev.mysql.com/doc/refman/5.0/en/call.html 。
似乎变量contact
是新插入记录的实例。 由于它包含新生成的id
(主键)字段值,因此您可以执行新查询以返回此新id
所需的timestamp
字段值。
该查询可能看起来像这样:
select timestamp_field from my_table where id=?
使用PreparedStatement
输入新的id
值并执行以获取所需的timestamp
字段值。
GeneratedKeyHolder
还具有两个方法: getKeyList()
返回所生成字段的Map<String,Object>
; 和getKeyList()
,为所有受影响的行生成一个生成键的列表。
参见GeneratedKeyHolder的 Java文档和自动生成键的Spring教程
另外,Spring的SimpleJdbcInsert具有生成密钥检索的方法。 另请参见方法SimpleJdbcInsert#usingGeneratedKeyColumns
java.sql.Connection
类中有2种方法,导致PreparedStatement执行返回选择的键列:
PreparedStatement prepareStatement(String sql,
int[] columnIndexes)
throws SQLException
PreparedStatement prepareStatement(String sql,
String[] columnNames)
throws SQLException
您不需要使用Spring KeyHolder和JDBCTemplate来执行此操作。
给您希望可以编号/命名您的时间戳列。 但是javadoc不需要或建议任何JDBC实现都可以返回非键列,因此使用这种方法很不走运:
创建一个默认的PreparedStatement对象,该对象能够返回由给定数组指定的自动生成的键。 此数组包含目标表中包含应返回的自动生成键的列的名称。
正如另一个答案中所建议的那样,可以切换到完全符合您想要的功能的存储过程(CallableStatement实际上是一个执行存储过程的PreparedStatement-即子类)。
可以通过new Timestamp(new Date())
填充预准备语句中的timestamp列-但您应该具有一种机制来在各个服务器之间同步时间(通常在Windows和* nix环境中使用)。 仅当尚未提供值时,触发器才可以设置时间戳。
作为应用程序和数据库设计的一部分,您需要致力于某些操作发生的地方的哲学。 如果数据库派生了所需的数据,则应用程序需要刷新数据-您必须支付单独的查询执行或插入和检索的组合存储过程的代价。
在MySQL数据库服务器端,解决此问题的方法很少。 您可以从在表上创建TRIGGER
开始。 由于TRIGGER
有限制并且不能返回数据,因此可以将TIMESTAMP
值设置为变量:
DEMILITER //
CREATE TRIGGER ai_tbl_name AFTER INSERT ON tbl_name
FOR EACH ROW
BEGIN
SET @TimeStamp = NEW.timestamp_column;
END;//
DELIMITER ;
要获取此时间戳记值,请运行以下命令:
SELECT @TimeStamp;
由于变量存储在内存中,因此无需再次打开任何表。
您走得更远。 您可以在MySQL中创建一个STORED PROCEDURE
来自动执行上述所有操作(示例代码,因为我不知道您表的详细信息):
DELIMITER //
DROP PROCEDURE IF EXISTS sp_procedure_name //
CREATE PROCEDURE sp_procedure_name (IN col1_val VARCHAR(25),
IN col2_val VARCHAR(25),
IN col3_val INT)
BEGIN
INSERT INTO tbl_name (col1, col2, col3)
VALUES (col1_val, col2_val, col3_val);
SELECT @TimeStamp;
END; //
DELIMITER ;
您可以使用以下代码运行此过程:
CALL sp_procedure_name(col1_val, col2_val, col3_val);
由于我不熟悉Java,因此您需要在代码方面完成它。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.