我正在连接到 SQLite 数据库。该程序应该根据用户选择的类别打印出信息。我在 SQLite 中测试了我的 SQL 语句,它有效。我遇到的问题是我似乎无法将占位符更改为相应的选择。我不断收到错误消息
the try-with-resources must either be a variable declaration or an expression denoting a reference to a final or effectively final variable
错误来自
ps.setInt(1, c.getCategory());
这是我的sql语句,你也可以在数据库类中找到它
SELECT productCode, productName, listPrice
FROM Product JOIN Category ON Product.categoryID = Category.categoryID
WHERE Category.categoryID = '?';
这是我的代码:
主要:
package productsbycategory;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class ProductsbyCategory_SharpR_Chap19 {
private static ProductDB pDB = new ProductDB();
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
//Setting header
System.out.println("Products by Category");
System.out.println();
int choice = 0;
while (choice != 999) {
//Setting menu options
System.out.print("""
CATEGORIES
1 - Guitars
2 - Basses
3 - Drums
Enter a category id (999 to exit): """);
//saving input from user
choice = Integer.parseInt(sc.nextLine());
//using switch case to select categories
switch(choice) {
case 1:
//pulling in the ProductDB Class
List<Product> product = pDB.getProduct(choice);
//Calling category class and passing choice into it
Category c = new Category(choice);
c.setCategoryID(choice);
//printing results
if (product == null) {
System.out.println("There are no products");
} else {
Product p;
for (int i = 0; i<product.size(); i++) {
p = product.get(i);
System.out.println(p.getCode() + "\t" + p.getName() + "\t" + p.getPrice());
}
}
System.out.println();
break;
case 2:
System.out.println("#2 works\n");
System.out.println();
break;
case 3:
System.out.println("#3 works\n");
System.out.println();
break;
default:
System.out.println("Bye!\n");
}
}//end of while
}
}
数据库:
package productsbycategory;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
public class ProductDB {
private Connection getConnection() throws SQLException {
//Connection to sqlite database
String dbURL = "jdbc:sqlite:guitar_shop.sqlite";
Connection connection = DriverManager.getConnection(dbURL);
return connection;
} //end of getConnection
public List<Product> getProduct(Category c) {
String sql = """
SELECT productCode, productName, listPrice
FROM Product JOIN Category ON Product.categoryID = Category.categoryID
WHERE Category.categoryID = '?';
""";
List<Product> product = new ArrayList<>();
try (Connection connection = getConnection();
PreparedStatement ps = connection.prepareStatement(sql);
ps.setInt(1, c.getCategoryID());
ResultSet rs = ps.executeQuery()) {
while (rs.next()) {
String code = rs.getString("productCode");
String name = rs.getString("productName");
double price = rs.getDouble("listPrice");
Product p = new Product(code, name, price);
product.add(p);
}//end of while
rs.close();
return product;
} catch (SQLException e){
System.err.println(e);
return null;
}
}
}
类别类:
package productsbycategory;
public class Category {
private int categoryID;
public Category(int categoryID) {
this.categoryID = categoryID;
}
public int getCategoryID() {
return categoryID;
}
public void setCategoryID(int categoryID) {
this.categoryID = categoryID;
}
}
产品类别:
package productsbycategory;
import java.text.NumberFormat;
public class Product {
private String code;
private String name;
private double price;
public Product() {};
public Product(String code, String name, double price){
this.code = code;
this.name = name;
this.price = price;
}
public String getCode() {
return code;
}
public void setCode(String code){
this.code = code;
}
public String getName(){
return name;
}
public void setName(String name){
this.name = name;
}
public double getPrice(){
NumberFormat formatter = NumberFormat.getCurrencyInstance();
formatter.format(price);
return price;
}
public void setPrice(double price){
this.price = price;
}
}
我查看了我的书和其他示例,我的语法似乎是正确的,所以我认为我在其他地方遗漏了一些东西。
我尝试改变
public List<Product> getProduct(Category c) {
到
public List<Product> getProduct(int c) {
但是,这不起作用,并且不会引入类别类。所以
getCategoryID()
不在那里。为了纠正这个问题,我使用 Category c = new Category(choice);
引入了它,但这仍然没有解决问题。我仍然收到同样的错误
try-with-resources 必须限制自己声明这些变量:
try (Connection connection = getConnection();
PreparedStatement ps = connection.prepareStatement(sql)) {
ps.setInt(1, c.getCategoryID());
try (ResultSet rs = ps.executeQuery()) {
List<Product> product = new ArrayList<>();
while (rs.next()) {
String code = rs.getString("productCode");
String name = rs.getString("productName");
double price = rs.getDouble("listPrice");
Product p = new Product(code, name, price);
product.add(p);
} //end of while
return product;
} // end of second try
} catch (SQLException e) {
System.getLogger().log(Level.ERROR, "...");
throw new IllegalArgumentException(e);
}
此外,要么不捕获异常,要么按照上面的方法重新抛出异常。还要避免空结果。 上面我使用了 System.Logger,它是任何日志库的外观。因此,在库本身中使用它,任何使用的应用程序都可以选择自己的日志库,例如 log4j。