javaweb之mysql数据库与jdbc(2)

接上一篇创建mysql数据库连接(java web之mysql数据库与jdbc(1));

1、Statement 对象存在安全隐患:

 Statement的执行,其实是进行sql语句的拼接,然后一起执行,不安全实例如下:

package JDBC2;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import JDBCUtil.JdbcUtil;//上一节封装的工具类
public class demo1 {
    public static void main(String[] args) {
        //boolean flog = login("lisi","123"); 登录成功
        boolean flog = login("lisi","100234khsdf88' or '1=1");//同样登录成功
        if(flog){
            System.out.println("登录成功");
        }
        else{
            System.out.println("登录失败");
        }
    }
    static Connection conn = null;
    static Statement st = null;
    static ResultSet rs = null;
    
    public static boolean login(String name,String passwd){
        try {
            conn =  JdbcUtil.getConnection();
            st = conn.createStatement();
            String sql = "select * from userinfo where username='"+ name  +"' and passwd='"+ passwd +"'";
            rs =  st.executeQuery(sql);
            while(rs.next()){
                String username = rs.getString("username");
                String password = rs.getString("passwd");
                if ("lisi".equals(username)&&"123".equals(password)){    
                    return true;
                }
            }
            
        } catch (Exception e) {
            e.printStackTrace();
        }
        finally{
            JdbcUtil.relase(rs, conn, st);
        }
        return false;
        
    }
    
}
View Code

在以上代码中login函数中的参数可看做从前端获取到的数据,第一次测试为数据库中存在的账户和密码,第二次为错误的密码,但能成功登陆:

原因:在Statement对sql语句拼接结果如下:

    select * from userinfo where username='lisi' and passwd='100234khsdf88' or '1=1'                                 

 拼接的sql语句中有数据库关键字or,数据库将 or 作为关键字处理,并不作为字符串处理。1=1为真, 所以整个sql语句就是一个永真的式子。====》在网络安全上称为sql注入漏洞;

2、解决方法:用PreparedStatement对象替换Statement对象

  PreparedStatement对象处理sql语句采用占位符,先判断整个sql语句的逻辑是否正确,如果正确再将数据放置于占位符处。实例如下:

package JDBC2;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import JDBCUtil.JdbcUtil;//上一节封装的工具类
public class demo2 {
    public static void main(String[] args) {
        boolean flog = login("lisi","123"); //登录成功
        //boolean flog = login("lisi","100234khsdf88' or '1=1");//登录失败
        if(flog){
            System.out.println("登录成功");
        }
        else{
            System.out.println("登录失败");
        }
    }
    static Connection conn = null;
    static PreparedStatement ps = null;
    static ResultSet rs = null;
    
    public static boolean login(String name,String passwd){
        try {
            conn =  JdbcUtil.getConnection();
            
            String sql = "select * from userinfo where username=? and passwd =?";
            ps = conn.prepareStatement(sql);
            ps.setString(1, name);//对占位符进行填充数据
            ps.setString(2, passwd);
            rs = ps.executeQuery();
            while(rs.next()){
                String username = rs.getString("username");
                String password = rs.getString("passwd");
                if ("lisi".equals(username)&&"123".equals(password)){    
                    return true;
                }
            }
            
        } catch (Exception e) {
            e.printStackTrace();
        }
        finally{
            JdbcUtil.relase(rs, conn, ps);
        }
        return false;
        
    }
    
}
View Code

注意:

(1)给占位符赋值 从左到右数过来,1 代表第一个问号, 永远你是1开始。
         ps.setString(1, userName);
        ps.setString(2, password);

      当传入的参数为XXX类型时调用setXXX()函数

(2)rs = ps.executeQuery();

  当对数据库进行增、删、更新操作时调用executeUpdate()函数,且不需要接收返回值,

  当对库进行查询时,查询的的结果保存在 ResultSet对象中,需要调用getXXX(“属性名”)方法取出值;如:

String username = rs.getString("username");

//username 为表中属性名,其类型为字符串型,因此用 rs.getString("username");

 

  

猜你喜欢

转载自www.cnblogs.com/ldd525/p/10461906.html