如何将ComboBox中的外键值插入MYSQL数据库

时间:2017-12-01 04:37:55

标签: java sql javafx

Java开发相当新,我在将ComboBox值插入数据库时​​遇到了一些问题。我的ComboBox包含来自+-----+---------+-------+ | BRN | Name | Amnt | +-----+---------+-------+ | 1 | John | 10 | | 2 | Belly | 4 | | 3 | John | 14 | | 4 | John | 5 | +-----+---------+-------+ 的{​​{1}}列和tblcourses主键的值,并在其上显示course_title的值。考虑到这一点,我想将course_id的主键插入course_title。我已经使用ObservableList来填充我的ComboBox,但我无法弄清楚如何插入外键。我还尝试使用course_id将外键显示在ComboBox上,但它仍然显示下面显示的错误。

这是我的插入代码:

tblusers

但它给了我一个错误:

getInt

我从错误中理解的是,我正在尝试将String插入到Integer中,因此需要获取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); 的主键。我怎样才能做到这一点?

这里是我的代码,用于填充ComboBox:

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)

1 个答案:

答案 0 :(得分:0)

在插入语句中,您仍然插入字符串值'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演示使用渲染器集来仅显示值。您可以在Action Listener或Property Listener中提取所选对象,然后从SimpleEntry对象中提取该键。 Swing演示在Action Listener中执行此操作,并在另一个文本字段中显示“Key:Value”。

javafx演示使用单元工厂自定义buttoncell(组合框显示为)和listcell(下拉列表)。可以通过向值属性添加侦听器来提取键值。

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);
            }
        }
    }
}