package com.bjpowernode.jdbc;
import java.sql.*;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
/*
怎样避免SQL注入?
SQL注入的根本原因是:先进行了字符串的拼接,然后再进行的编译
java.sql.Statement接口的特点:先进行字符串的拼接,然后再进行的编译
优点:使用statement可以进行sql语句的拼接
缺点:因为拼接的存在,可能给不法分子机会,到值SQL的注入
java.sql.PreparedStatement接口的特点:先进行SQL语句的编译,然后再进行SQL语句的传值
优点:避免SQL注入
缺点:无法进行字符拼接
思考:什么时候用Statement?
比如考虑用户自主选择升序降序(输入asc还是desc自主选择)
如果使用PreparedStatement则会自动添加'',变成 'desc' 或者 'asc' ,程序会报错
所以这种情况使用Statement,
所以一般开发者不会让用户自主输入,而是选择点击选择升序还是降序
*/
public class Text07 {
public static void main(String[] args) {
Map<String,String> userLoginInfo = initUI();
//连接数据验证用户名和密码是否正确
boolean ok = checkNameAndPwd
(userLoginInfo.get("loginName"),userLoginInfo.get("loginPwd"));
System.out.println(ok?" 登录成功":"登录失败");
}
private static boolean checkNameAndPwd(String loginName,String loginPwd) {
boolean ok = false; //默认登录失败
Connection conn = null;
PreparedStatement stmt = null;
ResultSet rs = null;
try {
Class.forName("com.mysql.cj.jdbc.Driver");
//2.获取连接
conn = DriverManager.getConnection
("jdbc:mysql://localhost:3306/bjpowernode",
"root", "123456");
//3.获取预编译的数据库操作对象
//注意:一个问号是一个占位符,一个占位符只能接收一个“值”
String sql = "select * from t_user where login_name = ? and login_pwd = ?";
stmt = conn.prepareStatement(sql);
//给占位符?传值
//JDBC所有下标都是从1开始
//怎么结局SQL注入的?即使用户信息中有SQL关键字,但不参加编译就没有事
stmt.setString(1,loginName);//1代表第1个?
stmt.setString(2,loginPwd);//2代表第2个?
//4.执行SQL
rs = stmt.executeQuery();
//5.处理查询结果集
if (rs.next()) {
//匹配到值,登录成功
ok = true;
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (stmt != null) {
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
return ok;
}
private static Map<String,String> initUI() {
//初始化一个界面,可以让用户输入用户名和密码
System.out.println("欢迎进入系统");
Scanner s = new Scanner(System.in);
System.out.println("账号:");
String longinName = s.next();
System.out.println("密码:");
String longinPwd = s.next();
//将用户名和密码放到MAP集合中
Map<String,String> userLoginInfo = new HashMap<>();
userLoginInfo.put("loginName",longinName);
userLoginInfo.put("loginPwd",longinPwd);
return userLoginInfo;
}
}
动力节点Statement与PreparedStatement比较
最新推荐文章于 2024-07-07 12:29:28 发布