最后再提醒一句,每次在测试JDBC程序的时候,一定要确保MySQL正在运行。
打开控制台(终端),输入mysql
如果没启动,则出现以下提示:
Mac端启动MySQL数据库,需要在系统便好设置中启动。
第一章:构建登录校验客户端
测试数据库:
当用户输入了正确的账号密码时,这个函数返回true,反之。
查看代码
public static boolean selectWithUsernamePassword(String username,String password){
Connection con = null;
Statement stmt = null;
ResultSet rs = null;
try {
//注册驱动
Class.forName("com.mysql.cj.jdbc.Driver");
String url = "jdbc:mysql://localhost:3306/jdbc_01?useUnicode=true&characterEncoding=UTF8";
con = DriverManager.getConnection(url,"root","88888888");
stmt = con.createStatement();
String sql = "select * from user where username ='"+username+"'and password ='"+password+"'";
System.out.println(sql);
rs = stmt.executeQuery(sql);
if(rs.next())
return true;
else
return false;
} catch (Exception e) {
e.printStackTrace();
}finally {
try {
if (rs != null)
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
try {
if (stmt != null)
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
try {
if (con != null)
con.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
return false;
}
其中,这一行时我们组拼的SQL语句:
String sql = "select * from user where username ='"+username+"'and password ='"+password+"'";
我们在main方法中调用测试一下:
selectWithUsernamePassword("remoo1","1234");
返回的是true;
若输入了数据库中不存在的数据,则返回false。
第二章:SQL注入攻击
当我们密码输入为:
selectWithUsernamePassword("nijsfies","1sadf' or '1'='1");
时,我们发现,无论你密码是否正确,最后都会输出true。
我们组拼的完整的SQL语句如下:
select * from user where username ='nijsfies'and password ='1234' or '1'='1'
相当于:select * from user where (username ='asd' and password = 'asd') or '1'='1'
where后面有两个条件:用户名密码满足xxx、‘1’=‘1’
显然‘1’=‘1’(SQL语句中等号为=,而不是==),
后面的每一条数据都满足1=1这个条件,
所以一定返回全部数据。
第三章:阻止SQL注入
如何解决?使用PreparedStatement()
查看代码
public static boolean safe_SelectWithUP(String username,String password){
Connection con = null;
//Statement stmt = null;
ResultSet rs = null;
PreparedStatement pstmt = null;
try {
//注册驱动
Class.forName("com.mysql.cj.jdbc.Driver");
String url = "jdbc:mysql://localhost:3306/jdbc_01?useUnicode=true&characterEncoding=UTF8";
con = DriverManager.getConnection(url,"root","88888888");
// stmt = con.createStatement();
// String sql = "select * from user where username ='"+username+"'and password ='"+password+"'";
// System.out.println(sql);
// rs = stmt.executeQuery(sql);
//?代表一个参数
String sql = "select * from user where username = ? and password = ?";
pstmt = con.prepareStatement(sql);
pstmt.setString(1,username);
pstmt.setString(2,password);
//上面已经传递了SQl语句了,这里直接执行就好了。
//SQL语句已经存储在pstmt内部了,并且对SQL注入攻击进行了防范。
rs = pstmt.executeQuery();
System.out.println(sql);
if(rs.next())
return true;
else
return false;
} catch (Exception e) {
e.printStackTrace();
}finally {
try {
if (rs != null)
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
try {
if (pstmt != null)
pstmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
try {
if (con != null)
con.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
return false;
}
测试结果: