Java 无法在SQLite中向表插入信息

Java 无法在SQLite中向表插入信息,java,sqlite,sql-insert,Java,Sqlite,Sql Insert,我正在创建一个简单的java程序来管理车库。 在程序中,您有一个登录窗口,之后您可以注册新用户。 问题是,当我想注册新用户时,在SELECT查询之后,当新用户不在数据库中时,程序被卡住了 我已确保所有连接都已关闭,并确保对SELECT使用正确的查询执行executeQuery,对INSERT使用正确的updateQuery 注册类别: class RegisterButtonListener implements ActionListener { Connection c

我正在创建一个简单的java程序来管理车库。 在程序中,您有一个登录窗口,之后您可以注册新用户。 问题是,当我想注册新用户时,在SELECT查询之后,当新用户不在数据库中时,程序被卡住了

我已确保所有连接都已关闭,并确保对SELECT使用正确的查询执行executeQuery,对INSERT使用正确的updateQuery

注册类别:

    class RegisterButtonListener implements ActionListener {
        Connection c = null;
        Statement stmt = null;
        String username, password;
        String selectUser="";

        @Override
        public void actionPerformed(ActionEvent arg0) { 
            if (garageView.getTxtNewPassword().getText().isEmpty() == false
                    && garageView.getTxtNewUsername().getText().isEmpty() == false){
                username = garageView.getTxtNewUsername().getText();
                password = garageView.getTxtNewPassword().getText();

                  try {
                     Class.forName("org.sqlite.JDBC");
                     c = DriverManager.getConnection("jdbc:sqlite:GarageDoctor.db");
                     c.setAutoCommit(false);
                     System.out.println("Opened database successfully - SELECT");

                     stmt=c.createStatement();
                     String selectSql = "SELECT NAME FROM USERS WHERE NAME = '"+username+"';";
                     ResultSet rs = stmt.executeQuery(selectSql);
                     while(rs.next()) {
                         selectUser+=rs.getString("name");
                         System.out.println(selectUser);
                         if(selectUser.equals(username)) {
                             JOptionPane.showMessageDialog(garageView, "User Already Exists!");
                             System.out.println("closing");
                             selectUser="";
                             rs.close();
                             stmt.close();
                             c.close();
                             System.out.println("closed");
                         }
                         else {    
                               System.out.println("user isn't in db, inserting now");
                               DBInsertNewUsers(username,password);  
                             }
                     }

                  } catch ( Exception e ) {
                     System.err.println( e.getClass().getName() + ": " + e.getMessage() );
                     System.exit(0);
                  }

            }else {
                JOptionPane.showMessageDialog(garageView, "Invalid input");
            }
        }
    }
这将导致DBInsertNewUsers:

    public void DBInsertNewUsers(String username,String password) {
        Connection c = null;
        Statement stmt = null;

        try {
        Class.forName("org.sqlite.JDBC");
        c = DriverManager.getConnection("jdbc:sqlite:GarageDoctor.db");
        c.setAutoCommit(false);
        System.out.println("Opened database successfully - Insert");


        stmt = c.createStatement();
        System.out.println("stmt = c.createStatement();");
        String sql = "INSERT INTO USERS (ID,PASSWORD,NAME) VALUES ("+i+",'"+password+"', '"+username+"');"; 
        stmt.executeUpdate(sql);
        System.out.println("stmt.executeUpdate(sql);");
        i++;

        stmt.close();
        c.commit();
        System.out.println("action done successfully - Insert");
        c.close();
        JOptionPane.showMessageDialog(garageView, "Register Success");
        }
        catch ( Exception e ) {
             System.err.println( e.getClass().getName() + ": " + e.getMessage() );
             System.exit(0);
        }       
    }
尝试注册新用户时,应用程序被卡住,最后一条控制台消息是:

Opened database successfully - SELECT

调用DBInsertNewUsers的代码位于whilers.next循环中。在没有匹配行的情况下,rs.next将返回false,因为没有行,控件将永远不会进入该循环。还应该考虑使用试用资源模式关闭资源并使用准备好的语句:

String query = "SELECT NAME FROM USERS WHERE NAME = ?";
try (Connection con = DriverManager.getConnection(myConnectionURL);
             PreparedStatement ps = con.prepareStatement(query);) { 
        ps.setString(1,username);
        try(ResultSet rs = stmt.executeQuery(selectSql);){
             if(rs.next()){
               selectUser+=rs.getString("name");
             }else{
               System.out.println("user isn't in db, inserting now");
               DBInsertNewUsers(username,password);  
             }
        }
}
SELECT NAME FROM USERS WHERE NAME = '"+username+"';
本声明:

String query = "SELECT NAME FROM USERS WHERE NAME = ?";
try (Connection con = DriverManager.getConnection(myConnectionURL);
             PreparedStatement ps = con.prepareStatement(query);) { 
        ps.setString(1,username);
        try(ResultSet rs = stmt.executeQuery(selectSql);){
             if(rs.next()){
               selectUser+=rs.getString("name");
             }else{
               System.out.println("user isn't in db, inserting now");
               DBInsertNewUsers(username,password);  
             }
        }
}
SELECT NAME FROM USERS WHERE NAME = '"+username+"';
仅当存在具有该用户名的行时,才会返回行。 在这种情况下,rs.next也是true,并且您进入一个循环,其中有一个if语句,条件:

selectUser.equals(username)
这肯定是真的。 因此else块永远不会执行。 您必须做的是删除while循环并仅保留if/else块:

@Override
public void actionPerformed(ActionEvent arg0) {
    if (garageView.getTxtNewPassword().getText().isEmpty() == false
            && garageView.getTxtNewUsername().getText().isEmpty() == false) {
        username = garageView.getTxtNewUsername().getText();
        password = garageView.getTxtNewPassword().getText();

        try {
            Class.forName("org.sqlite.JDBC");
            c = DriverManager.getConnection("jdbc:sqlite:GarageDoctor.db");
            c.setAutoCommit(false);
            System.out.println("Opened database successfully - SELECT");

            stmt = c.createStatement();
            String selectSql = "SELECT NAME FROM USERS WHERE NAME = '" + username + "';";
            ResultSet rs = stmt.executeQuery(selectSql);
            boolean exists = rs.next();
            System.out.println("closing");
            rs.close();
            stmt.close();
            c.close();
            System.out.println("closed");
            if (exists) {
                JOptionPane.showMessageDialog(garageView, "User Already Exists!");
                selectUser = "";
            } else {
                System.out.println("user isn't in db, inserting now");
                DBInsertNewUsers(username, password);
            }
        } catch (Exception e) {
            System.err.println(e.getClass().getName() + ": " + e.getMessage());
            System.exit(0);
        }

    } else {
        JOptionPane.showMessageDialog(garageView, "Invalid input");
    }
}
在DBInsertNewUsers内部,您还使用变量i设置列id的值。 从您发布的代码中,我无法找到它是如何初始化的,以及列id是否是主键。 因此,如果希望避免插入失败,则需要特别注意此部分。 在DBInsertNewUsers中,将语句的顺序更改为:

c.commit();
stmt.close();

忘了提到,“i”是静态整数,我用它来表示用户的递增ID。另外,您的建议最终让我进入了DBInsertNewUsers。问题是,我得到了SQLException:在命令“``stmt.close;``之后,数据库被锁定在调用DBInsertNewUsers之前,必须关闭所有对象。查看我编辑过的答案。我已经确保我的代码中的所有内容都与编辑过的版本相匹配,但我仍然得到了异常。遗憾的是,它仍然不起作用。到达以下行时发生异常:stmt.executeUpdatesql;在DBInsertNewUsersBeside控制台消息中,我从Eclipse获得的全部信息是:java.sql.SQLException:数据库被锁定