我正在创建包裹机器程序。每个parcel都有唯一的parcelID,导出到mysql db。问题是,每次运行程序时,程序都会从0开始计算parcelID。我正在寻找一个解决方案,它允许我检查数据库中的最后一个parcelID并在最后一个之后创建一行。
现在它看起来像这样:1。我正在通过java程序在db(成功)中创建一个新行。我在一段时间后关闭了这个程序。 3.我再次运行程序,我无法添加另一个新行,因为错误“重复输入'1'用于键'PRIMARY'”。
public static void post() throws Exception{
int parcelID = Parcel.generateID();
int clientMPNumber = Parcel.typeClientNumber();
int orderPassword = Parcel.generatePass();
try{
Connection con = getConnection();
PreparedStatement posted = con.prepareStatement("INSERT INTO Parcels.Orders (parcelID, clientMPNumber, orderPassword) VALUES ('"+parcelID+"', '"+clientMPNumber+"', '"+orderPassword+"')");
posted.executeUpdate();
}
catch(Exception e){
System.out.println(e);
}
finally{
System.out.println("Insert completed");
}
}
,方法是:
public static int generateID(){
parcelID = parcelID + 1;
return parcelID;
}
答案 0 :(得分:1)
我让数据库为您做繁重的工作 - 只需将GetRandDoubleBetween0And1()
列定义为parcelID
,而不是尝试自己设置其值。
答案 1 :(得分:1)
您不应该使用Id生成,只需在数据库表中创建auto_increment列
答案 2 :(得分:1)
如上所述here,将主键列定义为每个插入的自动递增,这样您的java代码就不必每次都手动计算主键值。
如果不是这种可能性,您需要说明您如何申报&初始化parcelID
。从当前代码开始,parcelID
看起来是一个类级别字段,每次运行时都会初始化为零,因此您始终可以获得相同的值 - 1
。您需要使用数据库中的最后一个值进行初始化。
另外,请执行有关PreparedStatement
答案 3 :(得分:1)
有几件事需要注意。
// parcelID should be an INT AUTOINCREMENT primary key.
try (PreparedStatement posted = con.prepareStatement(
"INSERT INTO Parcels.Orders (clientMPNumber, orderPassword) "
+ "VALUES (?, ?)",
Statement.RETURN_GENERATED_KEYS);
posted.setString(1, clientMPNumber);
posted.setString(2, orderPassword);
posted.executeUpdate();
try (ResultSet rsKey = posted.getGeneratedKeys()) {
if (rsKey.next()) {
int parcelID = rsKey.getInt(1);
return parcelID; // Or such
}try-with-resources
}
}
数据库可以最好地处理自动编号,这样两个事务同时不会窃取相同的“下一个”数字。
你应该关闭像Connection,PreparedStatement和ResultSet这样的东西。最好使用 try-with-resources 的一点尴尬语法来完成。即使在异常和返回时,它也会自动关闭。
PreparedStatements应与占位符?
一起使用。这需要在密码中转义'
之类的特殊字符。还可以防止 SQL注入。
文体更好地使用SQLException以上异常。甚至可能更好throws SQLException
。