PreparedStatement类
本小结来尝试写一个使用PreparedStatement类的登陆小程序,为什么不用上一节使用的Statement类呢?因为Statement类并不能保证所接受sql的安全性,打个比方来说从键盘上接username与password字符串并把所接受的字符串拼接在sql语句中则:
Scanner sc = new Scanner(System.in);
String username = sc.next(); //从键盘接受用户名与密码
String password = sc.next();
String sql = "SELECT * FROM userdemo WHERE username ="+ username +" AND password = "+passwor;
如果此时用户输入的password为"kkk or ‘a’=‘a’ ",因为’a’='a’必为真,则此SELECT语句就并没有起到判断用户是否存在的作用。
所以此时应该使用另外的类来执行sql语句即PreparedStatement类,需要注意的是PreparedStatement需要使用占位符?来表示暂时空缺的sql语句,下面是一个简单示例:
先建立一张用户密码表:
CREATE TABLE userdemo (
id INT PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(20) UNIQUE,
passwrod VARCHAR(20)
);
针对此表写的判断登陆小程序:
import java.sql.*;
import java.util.Scanner;
public class JavaDemo {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String username = sc.next(); //从键盘接受用户名与密码
String password = sc.next();
boolean flag = new JavaDemo().login(username,password);
if (flag){
System.out.println("登陆成功!!!");
} else {
System.out.println("用户名或密码错误!!!");
}
}
boolean login(String username,String password) {
Connection connection = null;
//在此不用Statement是为了解决安全问题,并且虽然PreparedStatement使用起来相对来说有些许麻烦,但是相对更高效
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
try {
Class.forName("com.mysql.cj.jdbc.Driver");
String sql = "SELECT * FROM userdemo WHERE username = ? AND password = ?";
connection = DriverManager.getConnection("jdbc:mysql:///DATABASE?serverTimezone=GMT","root","password");
preparedStatement = connection.prepareStatement(sql);
preparedStatement.setString(1,username); //设定第一个?代表的字符串(用户名)
preparedStatement.setString(2,password); //设定第二个?代表的字符串(密码)
resultSet = preparedStatement.executeQuery(); //运行写好的sql语句,将结果集存入ResultSet类中
return resultSet.next(); //就算使用了return语句任然会执行finally里的语句清理内存
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
} finally {
JdbcUtils.close(resultSet,preparedStatement,connection); //使用上一节编写好的简易工具类
}
return false;
}
}
/*
liuyifei
9528
登陆成功!!!
*/