我正在使用JavaFX编写程序,这是一种向任意数据库提交任意SQL语句的简单方法。可以将其视为ScriptRunner的GUI版本。查询在后台线程中运行。
我不知道在编译时需要的列数和类型。实际上,直到我从数据库取回ResultSet时,我才知道ResultSet中的内容。在这一点上,我想针对其JDBC数据类型适当地处理数据。例如,我为每列分配一个Comparator,以便用户可以对任何列上显示的数据进行排序,并且数据将正常运行。
我在StackOverflow上找到了关键代码(尽管此后我丢失了该帖子的链接)。我非常感谢那个帖子。该代码有效,但效果并不令人满意,主要是因为它使用“原始类型”并取消选中强制转换。从那时起,我进行了一些更改以尝试对其进行改进,但可能适得其反。如果有人可以帮助我解决这个问题,我将不胜感激。当然,还有一种更优雅的方法。如果这一切尽善尽美,那也是很好的信息。
顺便说一句,我的整个项目都位于.java文件中:我不使用FXML或.css。
此示例代码中的main()仅用于调用processRequest()中的代码。
我所追求的主要是如何最好地声明和操作变量:“数据”,“列”和“ tvResult”。以及是否还有其他特殊考虑。
tvResult:在GUI中显示的内容。
data:在ResultSet(dah)中返回的数据。
列:来自ResultSetMetaData的有关列的元数据。
我拥有的是:
ObservableList<ObservableList<?>> data = FXCollections.observableArrayList();
ArrayList<TableColumn<?,?>> columns = new ArrayList<>();
private TableView<ObservableList<?>> tvResult;
代码是我从各种教程,StackOverflow答案,书籍,博客等中收集的(请注意数据中的“ vogella.com”)。
表中的数据:
SQL:“从example.comments中选择*”。
输出: 1 || lars || myemail@gmail.com || http:\ www.vogella.com || 2009-09-14 ||摘要||我的第一条评论|| 2 ||斯蒂芬|| youremail@gmail.com || http:\ www.google.com || 2018-11-20 ||您的摘要在这里||您的第一条评论||
道歉 抱歉,这里有太多代码,我已尽力减少了代码,仍然有一个工作程序演示该问题。我剥离了在单独的线程,GUI内容和其他优点中运行的内容,以便我们可以专注于与我有关的代码。
它仍然比严格必要的时间长一点,但这是因为我想对processRequest()进行尽可能少的更改。它在String和Connection对象中接收SQL,并操纵提到的三个变量。
public class MySQLAccess extends Application {
ObservableList<ObservableList<?>> data = FXCollections.observableArrayList();
ArrayList<TableColumn<?,?>> columns = new ArrayList<>();
private TableView<ObservableList<?>> tvResult;
static MySQLAccess pgm;
/* ********************************************************************** **
** main()
** ********************************************************************** */
public static void main(String[] args) {
pgm = new MySQLAccess();
pgm.tvResult = new TableView<>();
Connection connection = null;
MysqlDataSource mySqlDataSource = new MysqlDataSource();
mySqlDataSource.setUrl("jdbc:mysql://" + "localhost" + ":3306/" + "StackOverflow");
mySqlDataSource.setUser("root");
mySqlDataSource.setPassword("");
DataSource dataSource = mySqlDataSource;
try {
connection = dataSource.getConnection();
pgm.processRequest("select * from example.comments", connection);
} catch (Exception e) {
System.out.println("error creating connection");
}
pgm.tvResult.getColumns().clear();
for (int j = 0; j < pgm.columns.size(); j++) {
TableColumn<?, ?> col = pgm.columns.get(j);
pgm.tvResult.getColumns().add((TableColumn<ObservableList<?>, ?>) col);
}
pgm.tvResult.setItems(pgm.data);
ObservableList<TableColumn<ObservableList<?>,?>> columns = pgm.tvResult.getColumns();
for (Object row : pgm.tvResult.getItems()) {
for (TableColumn column : columns) {
System.out.print(column.getCellObservableValue(row).getValue().toString() + " || ");
}
System.out.println();
}
}
/* ********************************************************************** **
** processRequest()
** ********************************************************************** */
private void processRequest(String sql, Connection connection) throws SQLException {
Statement statement = connection.createStatement();
ResultSet rs = statement.executeQuery(sql);
ResultSetMetaData rm = rs.getMetaData();
// Process Columns (assign the proper type to each)
int colCnt = rm.getColumnCount();
pgm.columns.clear();
for (int i = 0; i < colCnt; i++) {
final int k = i;
String columnName = rm.getColumnName(i + 1);
int columnType = rm.getColumnType(i + 1);
TableColumn col = new TableColumn(columnName);
col.setComparator(getComparator(columnType));
col.setCellValueFactory(
new Callback<CellDataFeatures<ObservableList<?>, String>, ObservableValue<String>>() {
@Override
public ObservableValue<String> call(
CellDataFeatures<ObservableList<?>, String> param) {
return new SimpleStringProperty(
param.getValue().get(k).toString());
}
});
pgm.columns.add(col);
}
// Process Rows
pgm.data.clear();
while (rs.next()) {
ObservableList<String> row = FXCollections.observableArrayList();
row.clear();
for (int i = 0; i < colCnt; i++) {
String str;
String hold = rs.getString(i + 1);
if ((hold == null) || (hold.isEmpty())) {
str = "";
} else {
str = String.valueOf(rs.getString(i + 1));
}
row.add(str);
}
pgm.data.add(row);
}
}
/* ********************************************************************** **
** getComparator()
** ********************************************************************** */
private Comparator<?> getComparator(int columnType) {
Comparator<?> comparator = null;
String objectType = DataTypeMapping.javaClass(columnType);
if (objectType.equals("String")) {
comparator = ((str_1, str_2) -> {
String int_1 = (String) str_1;
String int_2 = (String) str_2;
return int_1.compareTo(int_2);
});
} else if (objectType.equals("Integer")) {
comparator = ((str_1, str_2) -> {
Integer int_1 = Integer.parseInt((String) str_1);
Integer int_2 = Integer.parseInt((String) str_2);
return int_1.compareTo(int_2);
});
} else if (objectType.equals("Date")) {
comparator = ((str_1, str_2) -> {
Long date_1 = Long.parseLong((String) str_1);
Long date_2 = Long.parseLong((String) str_2);
return date_1.compareTo(date_2);
});
//
// .
// .
// .
//
} else {
comparator = null;
}
return comparator;
}
/* ********************************************************************** **
** start()
** *********************************************************************** */
@Override
public void start(Stage arg0) throws Exception {
}
}