[英]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.