我正在连接到一个SQLite数据库.该程序应该根据用户 Select 的类别打印信息.我在SQLite中测试了我的SQL语句,它可以工作.我遇到的问题是,我似乎无法将占位符更改为相应的选项.我一直收到错误信息

the try-with-resources must either be a variable declaration or an expression denoting a reference 至 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 至 exit):  """);
        
        //saving input from user
        choice = Integer.parseInt(sc.nextLine());
        
        //using switch case 至 select categories
        switch(choice) {
        case 1: 
            //pulling in the ProductDB Class
           List<Product> product = pDB.getProduct(choice);
           
           //Calling category class and passing choice in至 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 至 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) {

然而,这并不起作用,它也没有引入CATEGORY类.所以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> products = 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);
            products.add(p);
        } //end of while
        return products;
    } // end of second try
} catch (SQLException e) {
    System.getLogger().log(Level.ERROR, "...");
    throw new IllegalArgumentException(e);
}
// No return null!

解决方案是将一个try嵌套在另一个try中.

此外,要么不捕获异常,要么如上所述重新抛出它.也避免空结果. 上面我使用了System.Logger,它是任何日志(log)库的外观.因此,在库本身中使用它,任何使用它的应用程序都可以 Select 自己的日志(log)库,如log4j.

嘿,占位符?在需要时被填充、完全引用和转义.

WHERE Category.categoryID = ?

所以问号周围没有撇号.

Java相关问答推荐

获取拦截器内部的IP地址

使用ExecutorService时在ThreadFactory中触发自定义newThread函数

inteliJ中是否有一个功能可以自动在块注释中的/*后面添加一个空格?''

为什么我们仍然需要实现noArgsConstructor如果Java默认提供一个非参数化的构造函数?''

路径映射未发生

现场观看Android Studio中的变化

查找剩余的枚举

有没有办法让扩展变得多态?

如何为JavaFX Spring Boot应用程序制作Windows/MacOS/Linux安装程序

AbstractList保证溢出到其他方法

在Eclipse中可以使用外部字体吗?

如何在Maven Central上部署?

不能在 map 上移除折线

根据应用程序 Select 的语言检索数据

整数->;双取消框,但双->;int不';t开箱.为什么?

当我将JTextField的getText函数与相等的String进行比较时;t返回true

如何以事务方式向ibmmq发送消息

Springboot应用程序无法识别任何@RestController或@Service,我认为@Repository也无法识别

具有 DayOfWeek 列表的 JPA 实体

Swagger.io OpenApi v3.0 声明默认媒体类型