繁体   English   中英

如何从ComboBox插入外键值到MYSQL数据库

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM