索引超出范围。你应该如何将 resultSet 中的数据存储到 ArrayList 中?

IndexOutOfBounds. How should you store data from resultSet into an ArrayList?

所以,我有一个方法(应该)return 一个包含来自 sqlite 数据库的数据的字符串:

public String getLesson() throws ClassNotFoundException {
    ArrayList list = new ArrayList();

    int selectedColumn = tblOpenLesson.getSelectedColumn();
    int selectedRow = tblOpenLesson.getSelectedRow();
    String name = (String) tblOpenLesson.getModel().getValueAt(selectedRow, selectedColumn);

    try {
        Class.forName("org.sqlite.JDBC");
        Connection con = DriverManager.getConnection("jdbc:sqlite:sql_items.sqlite");
        Statement stmtGetLesson = con.createStatement();
        ResultSet rs = stmtGetLesson.executeQuery("SELECT * FROM lessons WHERE lesson_id  = '" + name + "';");

        if (rs.next()) {
            list.add(rs.getString("lesson"));
        }
    } catch (SQLException e) {
        JOptionPane.showMessageDialog(null, e);
    } catch (ClassNotFoundException ex) {
        Logger.getLogger(openLesson.class.getName()).log(Level.SEVERE, null, ex);
    }

    return (String) list.get(0);
}

我会使用该字符串来定位一个文本文件,通过该文件,其内容将显示在位于另一个 class

的 JTextPane 上
private void btnOpenLessonPopUpActionPerformed(java.awt.event.ActionEvent evt) {                                                   

    try {
        FileReader fr = new FileReader("Lessons\" + getLesson() + ".txt"); //this is Line 126

        try (BufferedReader br = new BufferedReader(fr)) {
            mainScreen.lessonPane.read(br, null); //  lessonPane is from another class
            br.close();
        } catch (IOException e) {
            System.out.println(e);
            this.setVisible(false);
        } catch (ClassNotFoundException ex) {
            Logger.getLogger(openLesson.class.getName()).log(Level.SEVERE, null, ex);
        }  
    } 

但是我收到了这个错误:

Exception in thread "AWT-EventQueue-0" java.lang.IndexOutOfBoundsException: Index: 0, Size: 0 at java.util.ArrayList.rangeCheck(ArrayList.java:657) at java.util.ArrayList.get(ArrayList.java:433) at mainWindow.openLesson.getLesson(openLesson.java:204) at mainWindow.openLesson.btnOpenLessonPopUpActionPerformed(openLesson.java:126) at mainWindow.openLesson.access[=12=]0(openLesson.java:19) at mainWindow.openLesson.actionPerformed(openLesson.java:60) at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2022) at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2348) at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:402) at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:259) at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:252) at java.awt.Component.processMouseEvent(Component.java:6539) at javax.swing.JComponent.processMouseEvent(JComponent.java:3324) at java.awt.Component.processEvent(Component.java:6304) at java.awt.Container.processEvent(Container.java:2239) at java.awt.Component.dispatchEventImpl(Component.java:4889) at java.awt.Container.dispatchEventImpl(Container.java:2297) at java.awt.Component.dispatchEvent(Component.java:4711) at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4904) at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4535) at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4476) at java.awt.Container.dispatchEventImpl(Container.java:2283) at java.awt.Window.dispatchEventImpl(Window.java:2746) at java.awt.Component.dispatchEvent(Component.java:4711) at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:760) at java.awt.EventQueue.access0(EventQueue.java:97) at java.awt.EventQueue.run(EventQueue.java:709) at java.awt.EventQueue.run(EventQueue.java:703) at java.security.AccessController.doPrivileged(Native Method) at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:74) at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:84) at java.awt.EventQueue.run(EventQueue.java:733) at java.awt.EventQueue.run(EventQueue.java:731) at java.security.AccessController.doPrivileged(Native Method) at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:74) at java.awt.EventQueue.dispatchEvent(EventQueue.java:730) at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:205) at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116) at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105) at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101) at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93) at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)

我想我不知道为什么会这样。我还是编程新手。

如果 sql 查询没有 return 任何行,最后一行将抛出异常,因为您的列表是空的。

 return (String) list.get(0);

所以要么将其更改为

if (!list.isEmpty() {
    return (String) list.get(0);
}
return null; //If list is empty

甚至更好,因为您只对第一行感兴趣,您可以跳过列表并替换

if (rs.next()) {
    list.add(rs.getString("lesson"));
}

if (rs.next()) {
    return rs.getString("lesson");
}

你还需要return方法的最后

return null;

不如你这样用

try {
    String lesson = getLesson();
    if (lesson != null) {
         //open file...
    }
...

如果不知道您的数据结构很难说,但是,从您的查询来看:"SELECT * FROM lessons WHERE lesson_id = '" + name + "';" 似乎您正在尝试将 lesson_idname 匹配你得到的教训。

也可能是 String name = (String) tblOpenLesson.getModel().getValueAt(selectedRow, selectedColumn); 没有达到您的预期。

另一方面,您确实需要研究准备好的语句。照原样,您的应用程序很容易受到 SQL 注入。

就我个人而言,我也会重构代码以便:

if (rs.next()) {
    list.add(rs.getString("lesson"));
}

变为:

if (rs.next()) {
    return rs.getString("lesson");
}

然后:return (String) list.get(0); 变成 return "";

您在尝试检索索引 0 处的值时抛出 IndexOutOfBounds 异常。这意味着您的 ArrayList 中没有添加任何内容。调用 next() 时,您的数据很可能不是有效行。