我有一个表INVENTORY
,其中包含2列[product
(主键) - quantity
]。我想在此表中插入一个含有数量的产品。
public boolean insertPackage(String product, int quantity)
throws SQLException, ClassNotFoundException {
System.out.println("Insert product to Invetory");
boolean flag=false;
sq = "INSERT INTO INVENTORY VALUES (?, ?)";
try {
Class.forName(typeDB);
c = DriverManager.getConnection(path);
stm = c.prepareStatement(sq);
PreparedStatement stm = c.prepareStatement(sq);
stm.setString(1, product);
stm.setInt(2, quantity);
int rowsAffected = stm.executeUpdate();
} catch (SQLException e) {
//There is already a same product in the Inventory
flag = true;
System.out.println(e.getMessage());
} finally {
if (stm != null)
stm.close();
if (c != null)
c.close();
}
return flag; //if the flag is true, then execute insert.
}
如果返回true,则我搜索此产品,检索数量,然后使用新数量更新表格。我想知道我是否认为这是一种检查如何进行插入的好方法,或者有更好的方法。
答案 0 :(得分:2)
在您的特定情况下,最简单的解决方案是使用SQLite的INSERT OR REPLACE
语法,如下所示:
public static void main(String[] args) {
String connectionURL = "jdbc:sqlite:"; // in-memory database
try (Connection conn = DriverManager.getConnection(connectionURL)) {
// set up test data
try (Statement st = conn.createStatement()) {
st.execute("CREATE TABLE INVENTORY (product VARCHAR(10) PRIMARY KEY, quantity INT)");
st.execute("INSERT INTO INVENTORY (product, quantity) VALUES ('one', 123)");
}
System.out.println("Initial state:");
dumpTable(conn);
// real code starts here
String sql = "INSERT OR REPLACE INTO INVENTORY (product, quantity) VALUES (?, ?)";
try (PreparedStatement ps = conn.prepareStatement(sql)) {
ps.setString(1, "two"); // product is new, so it will insert
ps.setInt(2, 234);
ps.executeUpdate();
System.out.println();
System.out.println("First change:");
dumpTable(conn);
ps.setString(1, "one"); // product already exists, so it will replace
ps.setInt(2, 999);
ps.executeUpdate();
System.out.println();
System.out.println("Second change:");
dumpTable(conn);
}
} catch (Exception e) {
e.printStackTrace(System.err);
}
}
private static void dumpTable(Connection conn) throws SQLException {
try (
Statement st = conn.createStatement();
ResultSet rs = st.executeQuery("SELECT product, quantity FROM INVENTORY ORDER BY product")) {
while (rs.next()) {
System.out.printf(
"product \"%s\" - quantity: %d%n",
rs.getString("product"),
rs.getInt("quantity"));
}
}
}
然而,SQLite中的INSERT OR REPLACE
实际上只是一个DELETE后跟INSERT,所以另一个解决方案是尝试先执行UPDATE,然后在UPDATE不影响任何行时执行INSERT。 (如果您倾向于进行比插入更多的更新,那可能会更有效。)
public static void main(String[] args) {
String connectionURL = "jdbc:sqlite:"; // in-memory database
try (Connection conn = DriverManager.getConnection(connectionURL)) {
// set up test data
try (Statement st = conn.createStatement()) {
st.execute("CREATE TABLE INVENTORY (product VARCHAR(10) PRIMARY KEY, quantity INT)");
st.execute("INSERT INTO INVENTORY (product, quantity) VALUES ('one', 123)");
}
System.out.println("Initial state:");
dumpTable(conn);
// real code starts here
updateQuantity("two", 234, conn);
System.out.println();
System.out.println("First update:");
dumpTable(conn);
updateQuantity("one", 999, conn);
System.out.println();
System.out.println("Second update:");
dumpTable(conn);
} catch (Exception e) {
e.printStackTrace(System.err);
}
}
private static void updateQuantity(String theProduct, int newQuantity, Connection conn) throws SQLException {
int rowsAffected;
try (PreparedStatement psUpdate = conn.prepareStatement("UPDATE INVENTORY SET quantity=? WHERE product=?")) {
psUpdate.setInt(1, newQuantity);
psUpdate.setString(2, theProduct);
rowsAffected = psUpdate.executeUpdate();
}
if (rowsAffected == 0) {
try (PreparedStatement psInsert = conn.prepareStatement("INSERT INTO INVENTORY (product, quantity) VALUES (?, ?)")) {
psInsert.setString(1, theProduct);
psInsert.setInt(2, newQuantity);
psInsert.executeUpdate();
}
}
}
private static void dumpTable(Connection conn) throws SQLException {
try (
Statement st = conn.createStatement();
ResultSet rs = st.executeQuery("SELECT product, quantity FROM INVENTORY ORDER BY product")) {
while (rs.next()) {
System.out.printf(
"product \"%s\" - quantity: %d%n",
rs.getString("product"),
rs.getInt("quantity"));
}
}
}
在这两种情况下,我们都会看到:
Initial state:
product "one" - quantity: 123
First update:
product "one" - quantity: 123
product "two" - quantity: 234
Second update:
product "one" - quantity: 999
product "two" - quantity: 234
答案 1 :(得分:1)
这不是检查产品是否存在的好方法,因为:
- 还有许多其他问题可能出错(很多不同的SQLExceptions,不仅仅是PK违规),你最终会得到一个真正的旗帜。
- 你不应该对正常发生的事情使用例外。
- 拖延并捕捉异常很慢。
试试这个:
1)使用count:
从产品中选择INVENTORYselect count(*) from INVENTORY where product = ?
2)如果计数等于0,则执行插入
否则增加数量。