如何使用JDBC数据源在JavaFX中构建多级TreeView?

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

在我的JavaFX程序中,我想使用数据库中的实时数据集动态生成树(我正在使用MariaDB,但它可以是任何SQL数据库。

我已经搜索了一堆,找不到我的问题的直接答案,所以我花了一些时间来学习JDBC ResultSet的工作方式,next()方法的工作方式以及while循环的工作方式。几次尝试和错误尝试最终使我得到了想要的结果,因此我想与他人分享,以防其他人发现自己处于我的位置。

请参阅下面的答案。

java sql javafx nested treeview
1个回答
0
投票

首先,我使用以下版本的MariaDB(10.4.12),Java(13.0.2.8),JavaFX(13.0.2)和MariaDB JDBC(2.6.0)。我不认为这会有所作为,但以防万一。.我正在使用FXML,这就是为什么您在任何地方都看不到任何UI格式的原因/

这是在我的JavaFX程序中生成TreeView的完整方法。然后,在生成StageScene对象后不久,从一个单独的类中调用它。

它们的关键部分是while循环,这对我来说很难。我最初以为我需要一个嵌套的while(rs.next())循环,但是后来我意识到这导致跳过行,因为每个rs.next()调用都与上一个相关,而不是与使用它的while循环相关。

还要注意,SQL语句很重要。如果该语句使结果混乱,则该方法将无法正常工作。

    public void generateTree(DataSource dataSource) {

        source = null;
        this.source = dataSource;

        Connection con = null;
        Statement stmt = null;

        TreeItem<String> rootTreeItem = new TreeItem<String>("EMT");
        rootTreeItem.setExpanded(true);
        emtTree.setRoot(rootTreeItem);

        TreeItem<String> site = null;
        TreeItem<String> plant = null;

        try {
            con = source.getConnection();
            try {
                stmt = con.createStatement();
                ResultSet rs = stmt.executeQuery("SELECT sites.siteid, sites.longname, plants.plantid, plants.siteplantid, plants.shortname FROM sites INNER JOIN plants ON plants.siteid=sites.siteid ORDER BY sites.longname ASC, plants.siteplantid ASC");

                String site1 = "";  //It's not possible for the site name to be "" in the result set because the database design prevents it.

                //Steps through the result set from first row item to last row item.
                while(rs.next()) {

                    //This bit prevents repeating the same first level items multiple times.
                    //I only want each site to appear once, and under each site is a list
                    //of plants.
                    if (!site1.equals(rs.getString("sites.longname"))) {
                        site = new TreeItem<String>(rs.getString("sites.longname"));
                        rootTreeItem.getChildren().add(site);
                        site1 = rs.getString("sites.longname");
                    }

                        //This section is never skipped and will add all the plants to a given
                        //site until the next site is reached in the result set, then the first if
                        //is triggered again and the process for the new site.
                        plant = new TreeItem<String>(rs.getInt("plants.siteplantid") + " " + rs.getString("plants.shortname"));
                        site.getChildren().add(plant);
                }
            } catch (SQLException e) {
                System.out.println("Statement Error");
                System.err.println("SQL State: " + ((SQLException)e).getSQLState());
                System.err.println("Error Code: " + ((SQLException)e).getErrorCode());
                System.err.println("Message: " + ((SQLException)e).getMessage());
                System.err.println("Cause: " + ((SQLException)e).getCause());
                return;
            }
        } catch (SQLException e) {
            e.printStackTrace();
            return;
        } finally {
            if (stmt != null) {
                try {
                    stmt.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if (con != null) {
                try {
                    con.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
    }

我可能会在将来找到改进它的方法,但是现在我很高兴能使它起作用。忽略混乱的异常处理-它正在进行中!

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