这是一个代码,我正在创建帮助用户登录到我的应用程序的方法登录,获取两个参数用户名和密码。
我希望将错误消息指定给用户,所以:
我的代码有效吗?我需要你的意见。我需要改进什么?改变?
这是方法
private String command;
private ResultSet resultSet;
private PreparedStatement statement;
private Connection connection;
String jdbcUrl = "jdbc:mysql://localhost:3306/registered";
String jdbcUser = "...";
String jdbcPassword = "...";
public boolean login(String eml, String pwd) {
try {
Class.forName("com.mysql.jdbc.Driver");
connection = DriverManager.getConnection(jdbcUrl, jdbcUser,
jdbcPassword);
command = "SELECT Email FROM users WHERE Email LIKE '" + eml + "';";
statement = connection.prepareStatement(command);
resultSet = statement.executeQuery();
if (!resultSet.isBeforeFirst()) {
System.out.println("Email (" + eml + ") is not registered ! ");
// show error message
} else {
command = "SELECT Email,Password FROM users WHERE Email LIKE '"
+ eml + "' AND Password LIKE '" + pwd + "';";
statement = connection.prepareStatement(command);
resultSet = statement.executeQuery();
if (!resultSet.isBeforeFirst()) {
System.out.println("Password for Email (" + eml
+ ") is incorrect ! ");
// show error message
}
else {
System.out.println("Logged in!");
}
}
} catch (SQLException e) {
System.out.println("SQLException: " + e.getMessage());
System.out.println("Vendor error: " + e.getErrorCode());
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return false;
}
答案 0 :(得分:2)
我的代码有效吗?
不,它不是。此方法性能的主要问题是您在此处手动打开连接:
Class.forName("com.mysql.jdbc.Driver");
connection = DriverManager.getConnection(jdbcUrl, jdbcUser, jdbcPassword);
这是一个瓶颈,因为您将打开与数据库的物理连接并关闭它,这是一个高成本的操作。这应替换为database connection pool并从那里检索连接。实现数据库连接池的一些选项:
更多信息:
我需要改进什么?改变?
除了获取连接的方式之外,当前代码容易SQL Injection,因为您连接字符串以生成SQL语句:
command = "SELECT Email FROM users WHERE Email LIKE '" + eml + "';";
相应地使用PreparedStatement
并设置参数:
command = "SELECT Email FROM users WHERE Email = ?";
statement = connection.prepareStatement(command);
statement.setString(1, eml);
resultSet = statement.executeQuery();
您的代码不是真正的问题,而是您的设计。用户的密码应仅在数据库中加密和验证。看起来您将密码存储为纯文本,这是用于学习目的的有效选项,但不能用于实际应用程序。