[英]How to insert foreign key values from ComboBox into MYSQL database
这是Java开发的新手,在将ComboBox值插入数据库时遇到一些问题。 我的组合框组成从值tblcourses
用的列course_title
和的主键course_id
和我显示的值course_title
到其上。 考虑到这一点,我想将course_id
的主键插入tblusers
。 我已使用ObservableList填充ComboBox,但无法弄清楚如何插入外键。 我也尝试过使用getInt
将外键显示到ComboBox上,但它仍然给我显示以下错误。
这是我的插入代码:
Statement stmt = conn.createStatement();
String query = "INSERT INTO tblusers (first_name, middle_initial, last_name, course_id, school_id, username,"
+ " password, privilege) VALUES ('txtFn', 'txtMi', 'txtLn', 'cmbSchool', 'cmbCourse', 'txtUser',"
+ " 'txtPass', 'student')";
stmt.executeUpdate(query);
但这给我一个错误:
com.mysql.jdbc.MysqlDataTruncation: Data truncation: Incorrect integer value: 'cmbSchool' for column 'course_id' at row 1
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4118)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4052)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2503)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2664)
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2788)
at com.mysql.jdbc.StatementImpl.executeUpdate(StatementImpl.java:1816)
at com.mysql.jdbc.StatementImpl.executeUpdate(StatementImpl.java:1730)
at elibraryserver.NewStudentController.registerButtonAction(NewStudentController.java:158)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at sun.reflect.misc.Trampoline.invoke(MethodUtil.java:71)
at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at sun.reflect.misc.MethodUtil.invoke(MethodUtil.java:275)
at javafx.fxml.FXMLLoader$MethodHandler.invoke(FXMLLoader.java:1769)
at javafx.fxml.FXMLLoader$ControllerMethodEventHandler.handle(FXMLLoader.java:1657)
at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:86)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:49)
at javafx.event.Event.fireEvent(Event.java:198)
at javafx.scene.Node.fireEvent(Node.java:8413)
at javafx.scene.control.Button.fire(Button.java:185)
at com.sun.javafx.scene.control.behavior.ButtonBehavior.mouseReleased(ButtonBehavior.java:182)
at com.sun.javafx.scene.control.skin.BehaviorSkinBase$1.handle(BehaviorSkinBase.java:96)
at com.sun.javafx.scene.control.skin.BehaviorSkinBase$1.handle(BehaviorSkinBase.java:89)
at com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(CompositeEventHandler.java:218)
at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:80)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54)
at javafx.event.Event.fireEvent(Event.java:198)
at javafx.scene.Scene$MouseHandler.process(Scene.java:3757)
at javafx.scene.Scene$MouseHandler.access$1500(Scene.java:3485)
at javafx.scene.Scene.impl_processMouseEvent(Scene.java:1762)
at javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2494)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:381)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:295)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent$353(GlassViewEventHandler.java:417)
at com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:389)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:416)
at com.sun.glass.ui.View.handleMouseEvent(View.java:555)
at com.sun.glass.ui.View.notifyMouse(View.java:937)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.lambda$null$147(WinApplication.java:177)
at java.lang.Thread.run(Thread.java:748)
我从错误中了解到的是,我试图将String插入Integer,因此需要获取tblcourses
的主键。 我该如何进行这项工作?
供参考,以下是我的代码,用于填充ComboBox:
public void populateCourse() throws SQLException {
try {
ObservableList data = FXCollections.observableArrayList();
String query = "SELECT course_title FROM tblcourses";
rs = conn.createStatement().executeQuery(query);
while (rs.next()) {
data.add(rs.getString("course_title"));
}
cmbCourse.setItems(data);
} catch (Exception e) {
e.printStackTrace();
}
}
在您的插入语句中,您仍在插入字符串值“ cmbSchool”。 您需要将其替换为包含键值的整数变量。 还要注意插入值的顺序。 您的插入内容应更像
Statement stmt = conn.createStatement();
String query = "INSERT INTO tblusers "
+ "(first_name, middle_initial, last_name, course_id, school_id, username, password, privilege)"
+ " VALUES "
+ "('" + txtFn + "','" + txtMi + "','" + txtLn + "'," + cmbCourseKey + "," + cmbSchoolKey + ","
+ "'" + txtUser + "','" + txtPass + "','student')";
stmt.executeUpdate(query);
请注意,insert语句是一个字符串,因此您需要将变量值转换为字符串,从而进行串联。 如果插入“ txtFn”作为值,则数据库中将列出该学生的名字“ txtFn”。 但是,如果txtFn =“ Bob”,则上面的字符串将创建为“ ... Values('Bob','...”。
在组合框和处理键/值对象方面,请理解组合框是一种选择多个对象之一的方法。 这些对象的作用取决于您。 如果希望对象是键/值对,则需要定义或使用合适的类来保存数据,然后用该数据填充组合框。 然后,您可以覆盖渲染器,以便组合框仅显示您想要显示的内容,例如值。 这样,您可以将复杂对象与组合框一起使用。
下面是两个使用java.util.AbstractMap.SimpleEntry<K,V>
作为对象的示例,第一个使用Swing,第二个使用javafx。 Swing演示使用渲染器集仅显示该值。 您可以在动作侦听器或属性侦听器中提取所选对象,然后从SimpleEntry对象提取键。 Swing演示程序在动作侦听器中执行此操作,并在另一个文本字段中显示“键:值”。
javafx演示使用单元工厂定制按钮单元(组合框显示为)和列表单元(下拉列表)。 可以通过将侦听器添加到value属性来提取键值。
import java.awt.AWTEvent;
import java.awt.Component;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.GraphicsConfiguration;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.Rectangle;
import java.awt.Toolkit;
import java.awt.Window;
import java.util.AbstractMap;
import java.util.AbstractMap.SimpleEntry;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.plaf.basic.BasicComboBoxRenderer;
/**
* This class demonstrates overriding the combo box renderer so that
* a given object can be displayed in the combo box in a particular way.
* In this demo, the class java.util.AbstractMap.SimpleEntry<K,V> will be used
* as the object and only the value will be shown in the combo box. The
* {@link SimpleEntryRenderer} class is used to override the standard renderer
* to do this.
*
*/
@SuppressWarnings("serial")
public class ComboBoxKeyValueDemo extends JFrame {
private JPanel contentPanel = null;
private JTextField fKeyValue = new JTextField();
private GridBagLayout gridBagLayout = new GridBagLayout();
private JLabel lComboBox = new JLabel();
private JLabel lKeyValue = new JLabel();
private JComboBox<SimpleEntry<Integer, String>> fComboBox = new JComboBox<>();
/**
* The SimpleEntryRenderer class is used to override the component
* renderer of the combo box and display the SimpleEntry<Integer,String>
* as the String value. Normally, the display would appear as "K=V"
*
*/
public class SimpleEntryRenderer extends BasicComboBoxRenderer {
@SuppressWarnings({ "rawtypes", "unchecked" })
@Override
public Component getListCellRendererComponent(JList list, Object value,
int index, boolean isSelected, boolean cellHasFocus) {
super.getListCellRendererComponent(list, value, index, isSelected,
cellHasFocus);
if (value != null) {
AbstractMap.SimpleEntry<Integer, String> item = (AbstractMap.SimpleEntry<Integer, String>) value;
setText(item.getValue());
}
return this;
}
}
public ComboBoxKeyValueDemo() {
enableEvents(AWTEvent.WINDOW_EVENT_MASK);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
try {
// Initialize the fields
jbInit();
} catch(Exception e) {
e.printStackTrace();
System.exit(1);
}
try {
setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
showCenterScreen(this);
setCursor(Cursor.getDefaultCursor());
} catch (Exception e) {
e.printStackTrace();
System.exit(1);
}
}
@SuppressWarnings({ "unchecked", "rawtypes" })
private void jbInit() {
contentPanel = (JPanel) this.getContentPane();
contentPanel.setLayout(gridBagLayout);
lComboBox.setText("Select entry:");
// Fill the comboBox with SimpleEntry objects
fComboBox.addItem(new SimpleEntry<Integer, String>(1, "-"));
fComboBox.addItem(new SimpleEntry<Integer, String>(2, "X"));
fComboBox.addItem(new SimpleEntry<Integer, String>(3, "Y"));
fComboBox.setMaximumRowCount(3);
// This is the important bit. The renderer determines how the
// the combo box displays the object it has selected. Here
// we'll replace the renderer with a custom one that will only
// display the value of the SimpleEntry object.
fComboBox.setRenderer(new SimpleEntryRenderer());
// For the demo, when the value of the comboBox changes,
// display the Key - Value in another field.
fComboBox.addActionListener(e -> {
JComboBox c = (JComboBox) e.getSource();
SimpleEntry<Integer, String> item = (SimpleEntry<Integer, String>) c.getSelectedItem();
fKeyValue.setText("Item " + item.getKey() + " : " + item.getValue());
});
lKeyValue.setText("Key : Value");
fKeyValue.setColumns(10);
fKeyValue.setEditable(false);
fComboBox.setSelectedIndex(0); // Will fire event to update the fKeyValue field.
// Layout the fields
contentPanel.add(lComboBox, new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0
,GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets(5, 5, 2, 5), 0, 0));
contentPanel.add(fComboBox, new GridBagConstraints(1, 0, 1, 1, 0.5, 0.0
,GridBagConstraints.WEST, GridBagConstraints.BOTH, new Insets(5, 2, 2, 5), 0, 0));
contentPanel.add(lKeyValue, new GridBagConstraints(0, 1, 1, 1, 0.0, 0.0
,GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets(2, 5, 2, 5), 0, 0));
contentPanel.add(fKeyValue, new GridBagConstraints(1, 1, 1, 1, 0.5, 0.0
,GridBagConstraints.WEST, GridBagConstraints.BOTH, new Insets(2, 2, 2, 5), 0, 0));
}
public static void main(String[] args) {
new ComboBoxKeyValueDemo();
}
/**
* Show in the center of the screen.
* (pack, set location and set visibility)
* @param window Window to position
*/
public static void showCenterScreen(Window window) {
positionScreen (window);
window.setVisible(true);
window.toFront();
} // showCenterScreen
/**
* Position window in center of the screen
* @param window Window to position
*/
public static void positionScreen (Window window)
{
window.pack();
// take into account task bar and other adornments
GraphicsConfiguration config = window.getGraphicsConfiguration();
Rectangle bounds = config.getBounds();
Dimension sSize = bounds.getSize();
Insets insets = Toolkit.getDefaultToolkit().getScreenInsets(config);
sSize.width -= (insets.left + insets.right);
sSize.height -= (insets.top + insets.bottom);
Dimension wSize = window.getSize();
// fit on window
if (wSize.height > sSize.height)
wSize.height = sSize.height;
if (wSize.width > sSize.width)
wSize.width = sSize.width;
window.setSize(wSize);
// Center
int x = (sSize.width - wSize.width) / 2;
int y = (sSize.height - wSize.height) / 2;
//
window.setLocation(bounds.x + x + insets.left, bounds.y + y + insets.top);
} // positionScreen
}
这是javafx演示:
import java.util.AbstractMap.SimpleEntry;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import javafx.application.Application;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.geometry.Insets;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.ComboBox;
import javafx.scene.control.Label;
import javafx.scene.control.ListCell;
import javafx.scene.control.ListView;
import javafx.scene.control.TextField;
import javafx.scene.layout.GridPane;
import javafx.scene.paint.Color;
import javafx.scene.paint.Paint;
import javafx.stage.Stage;
import javafx.util.Callback;
/**
* This class demonstrates custom cell factory so that
* a given object can be displayed in the combo box button cell and list view
* in a particular way. In this demo, the class java.util.AbstractMap.SimpleEntry<K,V>
* will be used as the object and only the value will be shown in the combo box.
*
*/
@SuppressWarnings("serial")
public class FXComboBoxHashMapDemo extends Application {
public static void main(String[] args) {
launch(args);
}
private final TextField fKeyValue = new TextField();
private final TextField fKeyValueDefault = new TextField();
private final Label lComboBox = new Label();
private final Label lComboBoxDefault = new Label();
private final Label lKeyValue = new Label();
private final Label lKeyValueDefault = new Label();
private ComboBox<Entry<Integer,String>> fComboBox = new ComboBox<>();
private ComboBox<Entry<Integer,String>> fComboBoxDefault = new ComboBox<>();
@SuppressWarnings("unchecked")
@Override
public void start(Stage stage) {
lComboBoxDefault.setText("Combo with default renderer: ");
fComboBoxDefault.getItems().setAll(populateHashMap());
fComboBoxDefault.setPrefWidth(100.0);
fComboBoxDefault.valueProperty().addListener(new ChangeListener() {
@SuppressWarnings("rawtypes")
@Override
public void changed(ObservableValue ov, Object arg1,
Object arg2) {
if (arg2 instanceof SimpleEntry<?,?>) {
SimpleEntry<Integer, String> entry = (SimpleEntry<Integer, String>) arg2;
fKeyValueDefault.setText("Key: " + entry.getKey() + " Value: " + entry.getValue());
}
}
});
lComboBox.setText("Combo with custom renderer: ");
fComboBox.getItems().setAll(populateHashMap());
// Customize the cell appearance
Callback<ListView<Map.Entry<Integer, String>>, ListCell<Map.Entry<Integer, String>>> customCallBack
= new Callback<ListView<Map.Entry<Integer, String>>, ListCell<Map.Entry<Integer, String>>>() {
@Override public ListCell<Map.Entry<Integer, String>> call(ListView<Map.Entry<Integer, String>> list) {
return new KeyValueFormatCell();
}
};
fComboBox.setButtonCell(customCallBack.call(null));
fComboBox.setCellFactory(customCallBack);
fComboBox.valueProperty().addListener(new ChangeListener<Object>() {
@SuppressWarnings("rawtypes")
@Override
public void changed(ObservableValue ov, Object arg1,
Object arg2) {
if (arg2 instanceof SimpleEntry<?,?>) {
SimpleEntry<Integer, String> entry = (SimpleEntry<Integer, String>) arg2;
fKeyValue.setText("Key: " + entry.getKey() + " Value: " + entry.getValue());
}
}
});
fComboBox.setPrefWidth(100.0);
lKeyValueDefault.setText("Key : Value selected: ");
lKeyValue.setText("Key : Value selected: ");
GridPane grid = new GridPane();
grid.setVgap(4);
grid.setHgap(10);
grid.setPadding(new Insets(5, 5, 5, 5));
grid.add(lComboBoxDefault, 0, 0);
grid.add(fComboBoxDefault, 1, 0);
grid.add(lKeyValueDefault, 2, 0);
grid.add(fKeyValueDefault, 3, 0);
grid.add(lComboBox, 0, 1);
grid.add(fComboBox, 1, 1);
grid.add(lKeyValue, 2, 1);
grid.add(fKeyValue, 3, 1);
stage.setTitle("FX ComboBox HashMap Demo");
Scene scene = new Scene(new Group(), 600,100);
Group root = (Group)scene.getRoot();
root.getChildren().add(grid);
stage.setScene(scene);
stage.show();
}
private List<SimpleEntry<Integer, String>> populateHashMap() {
List<SimpleEntry<Integer, String>> data = new ArrayList<SimpleEntry<Integer, String>>();
data.add(new SimpleEntry<Integer, String>(1, "Red"));
data.add(new SimpleEntry<Integer, String>(2, "Blue"));
data.add(new SimpleEntry<Integer, String>(3, "Green"));
return data;
}
public class KeyValueFormatCell extends ListCell<Map.Entry<Integer, String>> {
public KeyValueFormatCell() { }
@Override protected void updateItem(Map.Entry<Integer, String> item, boolean empty) {
super.updateItem(item, empty);
setText(item == null ? "" : item.getValue());
// For fun, change the text color to match the word
if (item != null) {
Paint fillColor = Color.BLACK;
String color = item.getValue();
if (color.equals("Red"))
fillColor = Color.RED;
else if (color.equals("Blue"))
fillColor = Color.BLUE;
if (color.equals("Green"))
fillColor = Color.GREEN;
this.setTextFill(fillColor);
}
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.