使用 JavaFX 从 MYSQL 数据库向 table 添加新用户无效
Adding new User to a table from MYSQL database using JavaFX is not working
我进行了搜索,但找不到解决方案,因为 google 搜索中的示例与我的编程风格不符。
编辑:我用addUser
方法解决了问题。
MySQL 中的日期格式为 YYY-MM-DD。在我的 DatePicker
中是 DD.MM.YYY。如何解决这个问题?
我是否必须更改数据库或 java 文件中的某些内容?
package application;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.geometry.Insets;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ButtonBar;
import javafx.scene.control.DatePicker;
import javafx.scene.control.Label;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.ColumnConstraints;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
import javafx.scene.text.Font;
public class Main extends Application {
private BorderPane root;
private Scene scene;
private GridPane grid;
private Label lblFirstName;
private Label lblLastName;
private Label lblDOB;
private TextField txtFirstName;
private TextField txtLastName;
private DatePicker txtDOB;
private Button btnAdd;
private Button btnCancel;
private Button btnUpdate;
private HBox hbox;
private ButtonBar buttonBar;
private TableView<User> table;
final ObservableList<User> data = FXCollections.observableArrayList();
Connection conn;
PreparedStatement pst = null;
ResultSet rs = null;
String url = "jdbc:mysql://localhost:3306/...";
String user = "root";
String password = "...";
@Override
public void start(Stage primaryStage) {
try {
CheckConnection();
root = new BorderPane();
grid = new GridPane();
// Create labels and textfields
lblFirstName = new Label("First Name");
lblFirstName.setFont(new Font("Times New Roman", 18));
lblFirstName.setPrefSize(100, 50);
lblLastName = new Label("Last Name");
lblLastName.setFont(new Font("Times New Roman", 18));
lblLastName.setPrefSize(100, 50);
lblDOB = new Label("DOB");
lblDOB.setFont(new Font("Times New Roman", 18));
lblDOB.setPrefSize(150, 50);
txtFirstName = new TextField();
txtLastName = new TextField();
txtDOB = new DatePicker();
// add to grid
grid.add(lblFirstName, 0, 0, 1, 1);
grid.add(txtFirstName, 1, 0, 1, 1);
grid.add(lblLastName, 0, 1, 1, 1);
grid.add(txtLastName, 1, 1, 1, 1);
grid.add(lblDOB, 0, 2, 1, 1);
grid.add(txtDOB, 1, 2, 1, 1);
grid.setHgap(10);
grid.setVgap(5);
grid.setPadding(new Insets(50, 10, 10, 30));
// Column constraints
ColumnConstraints column1 = new ColumnConstraints();
ColumnConstraints column2 = new ColumnConstraints();
grid.getColumnConstraints().add(column1);
grid.getColumnConstraints().add(column2);
column1.setPrefWidth(110);
column2.setPrefWidth(200);
// Buttons, Button Actions, ButtonBar
btnAdd = new Button("Add");
btnAdd.setPrefSize(40, 40);
btnAdd.setOnAction(e -> {
addUser();
});
btnCancel = new Button("Cancel");
btnCancel.setPrefSize(40, 40);
btnCancel.setOnAction(e -> {
clearFields();
});
btnUpdate = new Button("Update");
btnUpdate.setPrefSize(40, 40);
btnUpdate.setOnAction(e -> {
updateTable();
});
buttonBar = new ButtonBar();
buttonBar.getButtons().addAll(btnAdd, btnCancel, btnUpdate);
// add ButtonBar to HBox
hbox = new HBox();
hbox.getChildren().add(buttonBar);
hbox.setPadding(new Insets(10));
// create table
table = new TableView<>();
TableColumn<User, String> IDColumn = new TableColumn<User, String>("PersonID");
IDColumn.setPrefWidth(100);
IDColumn.setCellValueFactory(new PropertyValueFactory<>("personID"));
TableColumn<User, String> vornameColumn = new TableColumn<User, String>("First Name");
vornameColumn.setPrefWidth(100);
vornameColumn.setCellValueFactory(new PropertyValueFactory<>("firstName"));
TableColumn<User, String> nachnameColumn = new TableColumn<User, String>("Last Name");
nachnameColumn.setPrefWidth(100);
nachnameColumn.setCellValueFactory(new PropertyValueFactory<>("lastName"));
TableColumn<User, String> dobColumn = new TableColumn<User, String>("DOB");
dobColumn.setPrefWidth(100);
dobColumn.setCellValueFactory(new PropertyValueFactory<>("dob"));
table.getColumns().addAll(IDColumn, vornameColumn, nachnameColumn, dobColumn);
root.setCenter(table);
BorderPane.setMargin(table, new Insets(10, 10, 10, 10));
root.setLeft(grid);
root.setBottom(hbox);
scene = new Scene(root, 1000, 500);
scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
primaryStage.setScene(scene);
primaryStage.show();
} catch (Exception e) {
e.printStackTrace();
}
}
public void CheckConnection() {
conn = DBConnection.DbConnector();
if (conn == null) {
System.out.println("Connection Not Successful");
System.exit(1);
} else {
System.out.println("Connection Successful");
}
}
public void updateTable() {
data.clear();
try {
String query = "SELECT * FROM persons ";
pst = conn.prepareStatement(query);
rs = pst.executeQuery();
while (rs.next()) {
data.add(new User(rs.getString("PersonID"), rs.getString("Firstname"), rs.getString("Lastname"),
rs.getString("DOB")
));
table.setItems(data);
}
pst.close();
rs.close();
} catch (Exception e1) {
System.err.println(e1);
}
}
public void addUser() {
try {
conn = DBConnection.DbConnector();
String query = "INSERT into persons (Firstname, Lastname, DOB) VALUES (?, ?, ?)";
pst = conn.prepareStatement(query);
pst.setString(1, txtFirstName.getText());
pst.setString(2, txtLastName.getText());
pst.setString(3, ((TextField)txtDOB.getEditor()).getText());
pst.executeUpdate();
pst.close();
} catch (Exception e2) {
System.err.println(e2);
}
}
public void clearFields() {
txtFirstName.clear();
txtLastName.clear();
txtDOB.setValue(null);
}
public static void main(String[] args) {
launch(args);
}
}
package application;
import javafx.beans.property.SimpleStringProperty;
public class User {
private SimpleStringProperty personID;
private SimpleStringProperty firstName;
private SimpleStringProperty lastName;
private SimpleStringProperty dob;
public User(String pID, String fName, String lName, String DOB) {
this.personID = new SimpleStringProperty(pID);
this.firstName = new SimpleStringProperty(fName);
this.lastName = new SimpleStringProperty(lName);
this.dob = new SimpleStringProperty(DOB);
}
// getter , setter
public String getPersonID() {
return personID.get();
}
public void setPersonenID(String pID) {
personID.set(pID);
}
public String getFirstName() {
return firstName.get();
}
public void setFirstName(String fName) {
firstName.set(fName);
}
public String getLastName() {
return lastName.get();
}
public void setLastName(String lName) {
lastName.set(lName);
}
public String getDob() {
return dob.get();
}
public void setDob(String DOB) {
dob.set(DOB);
}
}
package application;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class DBConnection {
static String url ="jdbc:mysql://localhost:3306/...";
static String user ="root";
static String password="...";
public static Connection DbConnector(){
try{
Connection conn = DriverManager.getConnection(url, user, password);
return conn;
} catch (SQLException ex) {
System.err.println(ex.getMessage());
}
return null;
}
}
我从你那里了解到 that the data type of column DOB
, in database table persons
is DATE。因此,格式无关紧要,因为即使 DATE
类型的文档包括以下内容:
The DATE type is used for values with a date part but no time part. MySQL retrieves and displays DATE values in 'YYYY-MM-DD' format. The supported range is '1000-01-01' to '9999-12-31'.
我认为这是误导,因为根据 storage requirements 文档,DATE
值存储在三个字节中。所以该格式仅用于人类可读显示。
因此,由于格式无关紧要,您的问题基本上是如何获取 DatePicker 值并将其插入到 persons
数据库 table 的 DOB
列中。
方法getValue()
,在classDatePicker
,returns一个LocalDate.
如果您正在使用 MySQL 连接器,则根据 documentation,DATE
数据类型映射到 java class java.sql.Date
.
因此您需要将 java.time.LocalDate
转换为 java.sql.Date
。您可以通过在 class java.sql.Date
中调用静态方法 valueOf()
来完成此操作。参考 SO问题。
这是我重写的 addUser()
方法版本。它使用 try-with-resources.
public void addUser() {
String query = "INSERT into persons (Firstname, Lastname, DOB) VALUES (?, ?, ?)";
try (conn = DBConnection.DbConnector();
pst = conn.prepareStatement(query)) {
pst.setString(1, txtFirstName.getText());
pst.setString(2, txtLastName.getText());
pst.setDate(3, java.sql.Date.valueOf(txtDOB.getValue()));
pst.executeUpdate();
}
catch (SQLException xSql) {
xSql.printStackTrace();
}
}
如果你还想改变DatePicker
显示的日期格式,你可以设置它的converter property. The below code demonstrates how to do this using an anonymous class。
DatePicker txtDOB = new DatePicker();
txtDOB.setConverter(new StringConverter<LocalDate>() {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd-MM-yyyy", Locale.ENGLISH);
@Override
public String toString(LocalDate object) {
if (object != null) {
return object.format(formatter);
}
return null;
}
@Override
public LocalDate fromString(String string) {
if (string != null) {
return LocalDate.parse(string, formatter);
}
return null;
}
});
我进行了搜索,但找不到解决方案,因为 google 搜索中的示例与我的编程风格不符。
编辑:我用addUser
方法解决了问题。
MySQL 中的日期格式为 YYY-MM-DD。在我的 DatePicker
中是 DD.MM.YYY。如何解决这个问题?
我是否必须更改数据库或 java 文件中的某些内容?
package application;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.geometry.Insets;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ButtonBar;
import javafx.scene.control.DatePicker;
import javafx.scene.control.Label;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.ColumnConstraints;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
import javafx.scene.text.Font;
public class Main extends Application {
private BorderPane root;
private Scene scene;
private GridPane grid;
private Label lblFirstName;
private Label lblLastName;
private Label lblDOB;
private TextField txtFirstName;
private TextField txtLastName;
private DatePicker txtDOB;
private Button btnAdd;
private Button btnCancel;
private Button btnUpdate;
private HBox hbox;
private ButtonBar buttonBar;
private TableView<User> table;
final ObservableList<User> data = FXCollections.observableArrayList();
Connection conn;
PreparedStatement pst = null;
ResultSet rs = null;
String url = "jdbc:mysql://localhost:3306/...";
String user = "root";
String password = "...";
@Override
public void start(Stage primaryStage) {
try {
CheckConnection();
root = new BorderPane();
grid = new GridPane();
// Create labels and textfields
lblFirstName = new Label("First Name");
lblFirstName.setFont(new Font("Times New Roman", 18));
lblFirstName.setPrefSize(100, 50);
lblLastName = new Label("Last Name");
lblLastName.setFont(new Font("Times New Roman", 18));
lblLastName.setPrefSize(100, 50);
lblDOB = new Label("DOB");
lblDOB.setFont(new Font("Times New Roman", 18));
lblDOB.setPrefSize(150, 50);
txtFirstName = new TextField();
txtLastName = new TextField();
txtDOB = new DatePicker();
// add to grid
grid.add(lblFirstName, 0, 0, 1, 1);
grid.add(txtFirstName, 1, 0, 1, 1);
grid.add(lblLastName, 0, 1, 1, 1);
grid.add(txtLastName, 1, 1, 1, 1);
grid.add(lblDOB, 0, 2, 1, 1);
grid.add(txtDOB, 1, 2, 1, 1);
grid.setHgap(10);
grid.setVgap(5);
grid.setPadding(new Insets(50, 10, 10, 30));
// Column constraints
ColumnConstraints column1 = new ColumnConstraints();
ColumnConstraints column2 = new ColumnConstraints();
grid.getColumnConstraints().add(column1);
grid.getColumnConstraints().add(column2);
column1.setPrefWidth(110);
column2.setPrefWidth(200);
// Buttons, Button Actions, ButtonBar
btnAdd = new Button("Add");
btnAdd.setPrefSize(40, 40);
btnAdd.setOnAction(e -> {
addUser();
});
btnCancel = new Button("Cancel");
btnCancel.setPrefSize(40, 40);
btnCancel.setOnAction(e -> {
clearFields();
});
btnUpdate = new Button("Update");
btnUpdate.setPrefSize(40, 40);
btnUpdate.setOnAction(e -> {
updateTable();
});
buttonBar = new ButtonBar();
buttonBar.getButtons().addAll(btnAdd, btnCancel, btnUpdate);
// add ButtonBar to HBox
hbox = new HBox();
hbox.getChildren().add(buttonBar);
hbox.setPadding(new Insets(10));
// create table
table = new TableView<>();
TableColumn<User, String> IDColumn = new TableColumn<User, String>("PersonID");
IDColumn.setPrefWidth(100);
IDColumn.setCellValueFactory(new PropertyValueFactory<>("personID"));
TableColumn<User, String> vornameColumn = new TableColumn<User, String>("First Name");
vornameColumn.setPrefWidth(100);
vornameColumn.setCellValueFactory(new PropertyValueFactory<>("firstName"));
TableColumn<User, String> nachnameColumn = new TableColumn<User, String>("Last Name");
nachnameColumn.setPrefWidth(100);
nachnameColumn.setCellValueFactory(new PropertyValueFactory<>("lastName"));
TableColumn<User, String> dobColumn = new TableColumn<User, String>("DOB");
dobColumn.setPrefWidth(100);
dobColumn.setCellValueFactory(new PropertyValueFactory<>("dob"));
table.getColumns().addAll(IDColumn, vornameColumn, nachnameColumn, dobColumn);
root.setCenter(table);
BorderPane.setMargin(table, new Insets(10, 10, 10, 10));
root.setLeft(grid);
root.setBottom(hbox);
scene = new Scene(root, 1000, 500);
scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
primaryStage.setScene(scene);
primaryStage.show();
} catch (Exception e) {
e.printStackTrace();
}
}
public void CheckConnection() {
conn = DBConnection.DbConnector();
if (conn == null) {
System.out.println("Connection Not Successful");
System.exit(1);
} else {
System.out.println("Connection Successful");
}
}
public void updateTable() {
data.clear();
try {
String query = "SELECT * FROM persons ";
pst = conn.prepareStatement(query);
rs = pst.executeQuery();
while (rs.next()) {
data.add(new User(rs.getString("PersonID"), rs.getString("Firstname"), rs.getString("Lastname"),
rs.getString("DOB")
));
table.setItems(data);
}
pst.close();
rs.close();
} catch (Exception e1) {
System.err.println(e1);
}
}
public void addUser() {
try {
conn = DBConnection.DbConnector();
String query = "INSERT into persons (Firstname, Lastname, DOB) VALUES (?, ?, ?)";
pst = conn.prepareStatement(query);
pst.setString(1, txtFirstName.getText());
pst.setString(2, txtLastName.getText());
pst.setString(3, ((TextField)txtDOB.getEditor()).getText());
pst.executeUpdate();
pst.close();
} catch (Exception e2) {
System.err.println(e2);
}
}
public void clearFields() {
txtFirstName.clear();
txtLastName.clear();
txtDOB.setValue(null);
}
public static void main(String[] args) {
launch(args);
}
}
package application;
import javafx.beans.property.SimpleStringProperty;
public class User {
private SimpleStringProperty personID;
private SimpleStringProperty firstName;
private SimpleStringProperty lastName;
private SimpleStringProperty dob;
public User(String pID, String fName, String lName, String DOB) {
this.personID = new SimpleStringProperty(pID);
this.firstName = new SimpleStringProperty(fName);
this.lastName = new SimpleStringProperty(lName);
this.dob = new SimpleStringProperty(DOB);
}
// getter , setter
public String getPersonID() {
return personID.get();
}
public void setPersonenID(String pID) {
personID.set(pID);
}
public String getFirstName() {
return firstName.get();
}
public void setFirstName(String fName) {
firstName.set(fName);
}
public String getLastName() {
return lastName.get();
}
public void setLastName(String lName) {
lastName.set(lName);
}
public String getDob() {
return dob.get();
}
public void setDob(String DOB) {
dob.set(DOB);
}
}
package application;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class DBConnection {
static String url ="jdbc:mysql://localhost:3306/...";
static String user ="root";
static String password="...";
public static Connection DbConnector(){
try{
Connection conn = DriverManager.getConnection(url, user, password);
return conn;
} catch (SQLException ex) {
System.err.println(ex.getMessage());
}
return null;
}
}
我从你那里了解到 DOB
, in database table persons
is DATE。因此,格式无关紧要,因为即使 DATE
类型的文档包括以下内容:
The DATE type is used for values with a date part but no time part. MySQL retrieves and displays DATE values in 'YYYY-MM-DD' format. The supported range is '1000-01-01' to '9999-12-31'.
我认为这是误导,因为根据 storage requirements 文档,DATE
值存储在三个字节中。所以该格式仅用于人类可读显示。
因此,由于格式无关紧要,您的问题基本上是如何获取 DatePicker 值并将其插入到 persons
数据库 table 的 DOB
列中。
方法getValue()
,在classDatePicker
,returns一个LocalDate.
如果您正在使用 MySQL 连接器,则根据 documentation,DATE
数据类型映射到 java class java.sql.Date
.
因此您需要将 java.time.LocalDate
转换为 java.sql.Date
。您可以通过在 class java.sql.Date
中调用静态方法 valueOf()
来完成此操作。参考
这是我重写的 addUser()
方法版本。它使用 try-with-resources.
public void addUser() {
String query = "INSERT into persons (Firstname, Lastname, DOB) VALUES (?, ?, ?)";
try (conn = DBConnection.DbConnector();
pst = conn.prepareStatement(query)) {
pst.setString(1, txtFirstName.getText());
pst.setString(2, txtLastName.getText());
pst.setDate(3, java.sql.Date.valueOf(txtDOB.getValue()));
pst.executeUpdate();
}
catch (SQLException xSql) {
xSql.printStackTrace();
}
}
如果你还想改变DatePicker
显示的日期格式,你可以设置它的converter property. The below code demonstrates how to do this using an anonymous class。
DatePicker txtDOB = new DatePicker();
txtDOB.setConverter(new StringConverter<LocalDate>() {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd-MM-yyyy", Locale.ENGLISH);
@Override
public String toString(LocalDate object) {
if (object != null) {
return object.format(formatter);
}
return null;
}
@Override
public LocalDate fromString(String string) {
if (string != null) {
return LocalDate.parse(string, formatter);
}
return null;
}
});