每次在mysql表中插入或更新记录时,都会创建一个自动生成的时间戳。有没有办法以类似于使用keyholder返回新创建的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作为密钥持有者中的密钥一起返回,但它似乎不作为密钥返回?
答案 0 :(得分:1)
不是很满意,但我认为“不”是你问题的答案。我不知道任何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。
答案 1 :(得分:0)
变量contact
似乎是新插入记录的实例。由于它包含新生成的id
(主键)字段值,因此您可以执行新查询以返回此新timestamp
所需的id
字段值。
查询可能如下所示:
select timestamp_field from my_table where id=?
使用PreparedStatement
输入新的id
值并执行该值以获取所需的timestamp
字段值。
答案 2 :(得分:0)
GeneratedKeyHolder
还有两种方法:getKeyList()
返回Map<String,Object>
生成的字段;和getKeyList()
生成所有受影响行的生成键列表。
请参阅GeneratedKeyHolder和Spring tutorial of auto generated keys
的java文档另外,Spring的SimpleJdbcInsert具有生成密钥检索的方法。另见方法SimpleJdbcInsert#usingGeneratedKeyColumns
答案 3 :(得分:0)
java.sql.Connection
类中有2个方法导致PreparedStatement执行返回选定的键列:
PreparedStatement prepareStatement(String sql,
int[] columnIndexes)
throws SQLException
PreparedStatement prepareStatement(String sql,
String[] columnNames)
throws SQLException
您不需要使用Spring KeyHolder&amp; JDBCTemplate这样做。
希望您可以编号/命名您的时间戳列。但是javadoc并不要求或建议任何JDBC实现都可以返回非键列,所以你对这种方法感到不快:
创建一个能够返回自动生成的密钥的默认PreparedStatement对象 由给定数组指定。此数组包含目标中列的名称 包含应返回的自动生成的密钥的表。
正如另一个答案所建议的那样,可以切换到一个完全符合你想要的存储过程(CallableStatement实际上是一个执行存储过程的PreparedStatement--即一个子类)。
可以通过新的Timestamp(new Date())
填充预准备语句中的timestamp列 - 但是您应该有一个机制来同步各个服务器的时间(通常在Windows和* nix环境中使用) 。只有在尚未提供值的情况下,您的触发器才能设置时间戳。
作为您应用的一部分&amp;数据库设计,您需要承诺某些操作发生的原则。如果数据库导出所需数据,则应用程序需要刷新数据 - 您必须支付单独查询执行的价格或插入&amp;的组合存储过程。检索。
答案 4 :(得分:0)
在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,你需要用你的代码完成它。