尝试使用准备好的语句占位符提取信息时出现 Try-with-resources 错误

问题描述 投票:0回答:1

我正在连接到 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);
引入了它,但这仍然没有解决问题。我仍然收到同样的错误

java sqlite try-with-resources
1个回答
0
投票

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。

© www.soinside.com 2019 - 2024. All rights reserved.