![](/img/trans.png)
[英]MySQL auto_increment 10 instead of 1 when using spring jdbc
[英]Get AUTO_INCREMENT *before* database insertion in MySQL JDBC
我正在使用JDBC開發MySQL數據庫項目。 它使用與外鍵鏈接的父/子表。
TL; DR:我希望能夠在 INSERT
語句之前獲取表的AUTO_INCREMENT
ID。 我已經知道JDBC中的getGeneratedKeys()
方法可以在插入后執行此操作,但是我的應用程序在插入之前需要ID。 對於這個特定的應用程序,也許有更好的解決方案? 詳情如下:
在此應用程序的一部分中,用戶可以通過表單或控制台輸入來創建新項目以輸入詳細信息-其中一些詳細信息以新項目中“子項目”的形式出現。
這些輸入存儲在Java對象中,因此表的每一行對應於這些對象之一-以下是一些示例:
MainItem
- id (int)
- a bunch of other details...
MainItemTitle
- mainItemId (int)
- languageId (int)
- title (String)
ItemReference
- itemId (int) <-- this references MainItem id
- referenceId (int) <-- this references another MainItem id that is linked to the first
因此,基本上每個Java對象都代表MySQL數據庫相關表中的一行。
當我將輸入中的值存儲到對象中時,將使用一個偽ID,如下所示:
private static final int DUMMY_ID = 0;
...
MainItem item = new MainItem(DUMMY_ID, ...);
// I read each of the titles and initialise them using the same dummy id - e.g.
MainItemTitle title = new MainItemTitle(DUMMY_ID, 2, "Here is a a title");
// I am having trouble with initialising ItemReference so I will explain this later
讀取用戶輸入后,它們將存儲在“ holder”類中:
class MainItemValuesHolder {
MainItem item;
ArrayList<MainItemTitle> titles;
ArrayList<ItemReference> references;
// These get initialised and have getters and setters, omitted here for brevity's sake
}
...
MainItemValuesHolder values = new MainItemValuesHolder();
values.setMainItem(mainItem);
values.addTitle(englishTitle);
values.addTitle(germanTitle);
// etc...
在應用程序的最后一層(在另一個類中,將值所有者作為參數傳遞),將讀取“ holder”類中的數據並將其插入數據庫中:
// First insert the main item, belonging to the parent table
MainItem mainItem = values.getMainItem();
String insertStatement = mainItem.asInsertStatement(true); // true, ignore IDs
// this is an oversimplification of what actually happens, but basically constructs the SQL statement while *ignoring the ID*, because...
int actualId = DbConnection.insert(insertStatement);
// updates the database and returns the AUTO_INCREMENT id using the JDBC getGeneratedKeys() method
// Then do inserts on sub-items belonging to child tables
ArrayList<MainItemTitle> titles = values.getTitles();
for (MainItemTitle dummyTitle : titles) {
MainItemTitle actualTitle = dummyTitle.replaceForeignKey(actualId);
String insertStatement = actualTitle.asInsertStatement(false); // false, use the IDs in the object
DbConnection.insert(insertStatement);
}
現在,問題是將此過程用於ItemReference
。 因為它鏈接了兩個MainItem
,所以使用(或多個)虛擬ID預先構造對象會破壞這些關系。
最明顯的解決方案似乎是能夠預先獲取AUTO_INCREMENT
ID,這樣我就不需要使用虛擬ID。
我想另一種解決方案是在輸入數據后立即插入數據,但是我寧願將應用程序的不同功能保留在單獨的類中,因此一個類負責一個操作。 此外,通過在輸入數據后立即插入,如果用戶選擇在輸入“主要項目”,標題,參考等所有數據之前選擇取消,則現在需要刪除無效數據。
總之, 在插入之前如何獲得AUTO_INCREMENT
? 對於這個特定的應用程序有更好的解決方案嗎?
您不能在插入之前獲取該值。 您不知道桌上可能要采取的其他措施。 AUTO_INCREMENT可能不會增加1,您可能已經設置了該值,但是可以更改。
您可以使用臨時表在您的控制下通過鍵存儲數據。 我建議使用Uuid而不是ID,這樣您就可以認為它永遠是唯一的。 然后您的其他類可以將數據復制到活動表中,您仍然可以使用Uuid鏈接數據以在臨時表中找到相關數據,但是按照對數據庫有意義的順序將其寫入(因此,“根” '先記錄下來以獲得密鑰,然后在需要時使用它。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.