在我的JavaFX程序中,我想使用数据库中的实时数据集动态生成树(我正在使用MariaDB,但它可以是任何SQL数据库。
我已经搜索了一堆,找不到我的问题的直接答案,所以我花了一些时间来学习JDBC ResultSet
的工作方式,next()
方法的工作方式以及while
循环的工作方式。几次尝试和错误尝试最终使我得到了想要的结果,因此我想与他人分享,以防其他人发现自己处于我的位置。
请参阅下面的答案。
首先,我使用以下版本的MariaDB(10.4.12),Java(13.0.2.8),JavaFX(13.0.2)和MariaDB JDBC(2.6.0)。我不认为这会有所作为,但以防万一。.我正在使用FXML,这就是为什么您在任何地方都看不到任何UI格式的原因/
这是在我的JavaFX程序中生成TreeView的完整方法。然后,在生成Stage
和Scene
对象后不久,从一个单独的类中调用它。
它们的关键部分是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();
}
}
}
}
我可能会在将来找到改进它的方法,但是现在我很高兴能使它起作用。忽略混乱的异常处理-它正在进行中!