【问题标题】:Java - Cannot return/access ResultSet from MySQL StoredProcedureJava - 无法从 MySQL StoredProcedure 返回/访问 ResultSet
【发布时间】:2015-08-20 23:42:55
【问题描述】:

我在 MySQL 中有用户表,我创建了一个存储过程,以便当从 swing 文本字段获取用户名和密码时将它们传递到存储过程并了解是否存在该用户登录,但我实际上无法在 phpMyAdmin 中获取结果集存储过程正常工作,但在 netbeans 中无法获取结果集,并且运行时永远不会在控制台中停止,一直在运行。

我认为我的代码在其他地方没有问题,因为它是如此简单的代码。

这是我在 MySQL 中的存储过程

SELECT * FROM `users` WHERE `users`.`E-Mail` = @p0 AND `users`.`Password` = @p1

它需要两个参数 varchar,我之前尝试过将它们作为文本

这是我的java代码的具体部分

     public void loginPass(String email, String password){

     try {
        DriverManager.registerDriver((Driver) Class.forName("com.mysql.jdbc.Driver").newInstance());
        Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/askdocdb","root","");
        CallableStatement mystatement = connection.prepareCall("{CALL sp_Login (?, ?)}");
        mystatement.setString(1, email);
        mystatement.setString(2, password);

        // mystatement.setString("@p0", email);
        // mystatement.setString("@p1", password);


         boolean situation = mystatement.execute();
         System.out.println(situation);
        // resultset = mystatement.executeQuery();
         resultset = mystatement.getResultSet();

         String res =    resultset.getString(2);
         System.out.println(res);

         //    resultset = mystatement.executeQuery();
        while(resultset.next()){
            System.out.println("asdsad");
        }
        resultset.close();

    } catch (Exception e) {
    }
}

注释行的原因,我尝试了任何可能的语法组合

情况返回真

res 不返回

不能进入while语句

感谢您现在的支持和 cmets。

【问题讨论】:

  • 您是否特别需要使用存储过程?
  • 其实我不需要,但我不想在java端写所有的查询,我只想执行数据库中已经存在的东西。

标签: java mysql swing stored-procedures


【解决方案1】:

很难说你的代码到底出了什么问题,因为如果你选择使用存储过程来完成这个简单的任务,有很多可能的失败点(过程中的语法不正确,获取返回值的问题) JDBC 等)。我只需通过 JDBC 运行 SQL 查询来检查凭据:

public void registerDriver() {
    try {
        DriverManager.registerDriver((Driver) Class.forName(
                "com.mysql.jdbc.Driver").newInstance());
    } catch (InstantiationException | IllegalAccessException
            | ClassNotFoundException | SQLException e) {
        throw new RuntimeException("Could not register MySQL driver!", e);
    }
}

public boolean checkLogin(String email, String password) {      

    try (Connection connection = DriverManager.getConnection(
            "jdbc:mysql://localhost:3306/askdocdb", "root", "");
            PreparedStatement ps = connection
                    .prepareStatement("SELECT 1 FROM users WHERE " 
                            + "E-Mail = ? AND Password = ?")) {

        ps.setString(1, email);
        ps.setString(2, password);

        try (ResultSet rs = ps.executeQuery()) {
            if (rs.next()) {
                return true; // username and password match
            } else {
                return false; // no row returned, i.e. no match
            }
        }
    } catch (SQLException e) {
        throw new RuntimeException(
                "Error while checking user credentials!", e);
    }
}

改变了什么:

  • JDBC 驱动程序注册已被提取到一个单独的方法 (registerDriver()) 中,您只需调用一次(例如在程序启动后),而不是每次检查凭据时。
  • ConnectionPreparedStatementResultSet 等资源现在可以正常关闭(即使抛出异常),因为它们是通过 the try-with-resources statement 声明的。
  • 该方法现在返回一个与凭据是否有效相对应的布尔值,从而更易于在调用代码中使用。
  • 无法处理的异常(例如SQLException)被重新抛出为RuntimeExceptions(而不是仅仅将它们吞入一个空的catch 块中)。
    • 基本上,当抛出SQLException 时,要么代码中存在编程错误(无效的查询语法),要么数据库出现严重错误。在任何一种情况下,唯一的选择通常是停止您的程序。如果您想在调用方法中处理这种情况,可以在方法签名中声明throws SQLException

最后,需要指出的是,您不应该将密码以纯文本形式存储在数据库中,以避免任何对数据库具有读取权限的人以任意用户身份登录。相反,您应该存储密码哈希,甚至更好的是盐渍哈希。更多关于这个例如在Best way to store password in database

【讨论】:

  • 而且我首先想到了密码问题,但我是 Java 和数据库的初学者,所以我只想做一个非常简单的例子,但我会研究你的建议,再次感谢你
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-12-05
  • 2021-11-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-02-06
  • 1970-01-01
相关资源
最近更新 更多