【问题标题】:Db Query not executing on Button ClickDb 查询未在按钮单击时执行
【发布时间】:2015-06-30 08:37:47
【问题描述】:

我在使用 GUI 时遇到问题。当我单击JButton b1 时,当JTextField text 中的文本为空时,它不会捕获异常。

单击按钮时查询只执行一次,如果再次单击它会抛出异常并且查询没有执行

代码:

public class A extends JFrame{


    private JTextField text;
    private JButton b1;
    private JLabel l1;
    private Connection conn;
    private Statement state;
    private ResultSet set;

    String server = "jdbc:mysql://localhost";
    String user="tim";
    String pass="u";
    //query enter in textfield | select * from universty.student where rollno=2

    public A() throws ClassNotFoundException, SQLException{

        super("Frame");
           Class.forName("com.mysql.jdbc.Driver");
                    conn = DriverManager.getConnection(server,user,pass);

                    state = conn.createStatement();

                    getContentPane().setLayout(null);




        text = new JTextField();
        text.setBounds(35, 132, 346, 35);
        getContentPane().add(text);

        l1= new JLabel();
        l1.setFont(new Font("Tahoma", Font.PLAIN, 22));
        l1.setBounds(35, 305, 384, 27);
        getContentPane().add(l1);


        b1 = new JButton("Submit");
        b1.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {

                try{

            String  query = text.getText();

                set = state.executeQuery(query);


            set.next();
            String  answer = set.getString(2);


               l1.setText(answer);          





                }
                catch (Exception e){
                    JOptionPane.showMessageDialog( null, 
                            e.getMessage(), "Database error", 
                            JOptionPane.ERROR_MESSAGE );            
                    return;
                }
                finally{
                    try{
                        set.close();
                        state.close();
                        conn.close();

                    }
                        catch(Exception e){
                            e.printStackTrace();
                        }

                }

            }});
        b1.setBounds(132, 178, 129, 35);
        getContentPane().add(b1);






        setSize(450,450);
        setLocationRelativeTo(null);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setResizable(false);
        setVisible(true);

    }   

}

主要方法:

public class Main {

    public static void main(String args[]) throws ClassNotFoundException, SQLException{

    A obj = new A();

    }

}

【问题讨论】:

  • throws 在您的主要方法中有一个非常糟糕的品味。使用你的 try/catch 块来处理你的异常。
  • 另外,您将 DB 代码与 GUI 代码混合,这通常不是一个好主意,您应该将其分离到服务和 DAO 层

标签: java database swing


【解决方案1】:

您应该打开和关闭您的数据库连接:

actionPerformed()

因为当您调用构造函数时,它会打开数据库连接并再次关闭它。当您单击时,数据库连接已再次关闭

public void actionPerformed(ActionEvent arg0) {
      conn = DriverManager.getConnection(server,user,pass);
      state = conn.createStatement();
      //do query here
      set.close();
      state.close()
      conn.close();
}

【讨论】:

  • 在您的 actionPeformed 方法中打开和关闭数据库连接
  • 感谢帮助 Peter P 我明白你的答案
【解决方案2】:

在第一次单击结束时,您使用以下语句关闭所有内容。

            finally{
                try{
                    set.close();
                    state.close();
                    conn.close();

这就是为什么。

__UPDATE__

我被要求提供一个解决方案。实际上,我通过指出问题已经给出了一半的解决方案。但让我更详细地说,因为我被问到了。

简单的解决方案是不要关闭连接或语句或其他任何东西。但这将是一个糟糕的解决方案,因为不必要的资源可能会保持活动状态。没必要。

我不知道您的申请。所以我不能给你一个准确的答案,但我可以给你一些指导方针,帮助你自己找到正确的答案。

只要您需要,请保留资源。一旦你完成了它们,就摆脱它们。对于这种情况,如果需要用户单击该按钮并在数据库中进行更改,则不要关闭连接等,而是重用它们。如果是多页应用程序,可以在用户移动到另一个页面时关闭这些资源。 (或活动,如果它是移动应用程序)。

我希望它有意义 =]

【讨论】:

  • 那么解决办法是什么
【解决方案3】:

我不确定您的代码的用途,但您应该尝试将视图逻辑与业务逻辑分开。还允许用户从文本框运行 SQL 并提交按钮听起来很危险,但如果这确实是您想要做的,这里是您可以使用的一种实现。请注意,这里的 DAO 不是真正的 DAO,因为您要执行查询的方式

    public class A extends JFrame {

        private final JTextField text;
        private final JButton b1;
        private final JLabel l1;

        private AService service;

        public A() {
            super("Frame");
            service = new AServiceImpl(new ADAOJDBCImpl());
            javax.swing.SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    createAndShowGUI();
                }
            });
        }

        private static void createAndShowGUI() {
            text = new JTextField();
            text.setBounds(35, 132, 346, 35);
            getContentPane().add(text);

            l1= new JLabel();
            l1.setFont(new Font("Tahoma", Font.PLAIN, 22));
            l1.setBounds(35, 305, 384, 27);
            getContentPane().add(l1);

            b1 = new JButton("Submit");
            b1.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent arg0) {
                       String  query = text.getText();
                       try {
                           String answer = service.executeQuery(query);
                           l1.setText(answer);
                       } catch (SQLException e){
                        JOptionPane.showMessageDialog( null, 
                                e.getMessage(), "Database error", 
                                JOptionPane.ERROR_MESSAGE );            
                        return;
                    }

                }});
            b1.setBounds(132, 178, 129, 35);
            getContentPane().add(b1);
            setSize(450,450);
            setLocationRelativeTo(null);
            setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            setResizable(false);
            pack();
            setVisible(true);
        }
    }

    public interface AService {
        public String executeQuery(String query) throws SQLException;
    }

    public class AServiceImpl implements AService {

        private ADAO dao;

        public AServiceImpl(ADAO dao) {
            this.dao = doa;
        }

        @Override
        public String executeQuery(String query) throws SQLException {
            return dao.executeQuery();
        }

    }

    /**
    * Note usually a DAO is specfically for accessing data, NOT
    * for executing User defined queries from a GUI text box
    * so it would usually have methods such as add, find, delete, update etc.
    */
    public interface ADAO {
        public String executeQuery(String query) throws SQLException;
    }

    public class ADAOJDBCImpl implements ADAO {

        @Override
        public String executeQuery(String query) throws SQLException {
            String server = "jdbc:mysql://localhost";
            String user="tim";
            String pass="u";            

            String answer = "":
            try (Connection conn = DriverManager.getConnection(server,user,pass);
                 Statement state = conn.createStatement();
                 ResultSet set = state.executeQuery(query);) {

                if(set.next()) {
                    answer = set.getString(2);
                }
            }
            return answer;
        }

    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-28
    • 2021-06-14
    • 2021-03-13
    • 1970-01-01
    相关资源
    最近更新 更多