zoukankan      html  css  js  c++  java
  • 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");

     

      

  • 相关阅读:
    uni-app 小程序实现scroll-view 横向滑动效果的坑
    kafka常用指令
    vue之每个页面设置单独的title,keywords,description等
    mysql定时备份
    zabbix-mysql备份脚本
    第十五课:企业案例-kubernetes高可用集群架构设计
    第十四课:企业案例-微服务实现业务架构
    第十三课:微服务基本知识-微服务调用及运行过程
    第十二课:微服务基本知识-微服务组件
    第十一课:微服务基本知识-微服务架构与框架介绍
  • 原文地址:https://www.cnblogs.com/ldd525/p/10461906.html
Copyright © 2011-2022 走看看