JDBC学习——简单学习以及sql注入现象!

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: JDBC学习——简单学习以及sql注入现象!

JDBC (java语言连接数据库)是sun公司制定的一套接口

 JDBC 代码编写的六步

1、注册驱动

2、获取连接

3、获取数据库操作对象

4、执行sql语句

5、处理查询结果集

6、释放资源

1、注册驱动

 有两种方式:

 //第一种
Driver driver=new com.mysql.jdbc.Driver();
DriverManager.registerDriver(driver);
//第二种注册方式(常用)
 Class.forName("com.mysql.jdbc.Driver");

在编写JDBC的时候可以通过使用资源绑定器(xxx.properties) 绑定属性配置文件和工具类的创建去让代码看起来更简介方便。

 将连接数据库的所有信息配置到文件当中xxx.properties,因为实际开发中不建议把连接数据库的信息 写死到java程序中

 

案例:模拟用户登录

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.*;
/**
 *  实现功能
 *      1. 需求:模拟用户登录功能的实现
 *      2. 业务描述:
 *          程序运行的 时候提供一个输入的入口  让用户可以输入用户名和密码
 *          用户输入后提交信息 java程序收集到用户信息
 *          java程序验证用户名和密码是否合法
 *          合法:显示登录成功
 *          不合法:显示登录失败
 *      3. 数据的准备
 *          实际开发中表的设计会使用专业的建模工具
 *          +----+----------+-----------+----------+
 *          | id | loginPwd | loginName | realName |
 *          +----+----------+-----------+----------+
 *          |  1 | 111      | 1         | 1        |
 *          |  2 | 222      | 2         | 2        |
 *          +----+----------+-----------+----------+
 *      4.当前程序存在的问题
 *          用户名:fdsa
 *          密码:fdsa' or '1'='1
 *          登录成功!
 *          这种现象叫做SQL注入(安全隐患)(黑客经常使用)
 *       5.导致SQL注入的主要原因
 *          where loginPwd = 'fdsa' or '1'='1'
 *          这样会导致sql 的代码变成上面那样  因为1=1 恒成立  所以会查询到所有字段
 *          用户输入的信息含有sql语句的关键字,
 *          而最重要的是这些关键字参与了sql语句 的编译过程
 *          导致sql语句原意扭曲 进而达到sql注入
 */
public class JDBC_Test06 {
    public static void main(String[] args) {
        //初始化一个界面
        /* 该方法要返回一个容器 既可以存用户名 又可以存密码*/
        Map<String,String> userLoginInfo = initUI();
        //验证用户名loginName和密码loginPwd
        boolean loginResult = login(userLoginInfo);
        System.out.println(loginResult ? "登录成功!":"登录失败!");
    }
    /**
     * 初始化用户界面
     * @return loginName loginPwd 等登录信息
     */
    private static Map<String,String> initUI(){
        Scanner scanner=new Scanner(System.in);
        System.out.print("用户名:");
        String loginName = scanner.nextLine();
        System.out.print("密码:");
        String loginPwd = scanner.nextLine();
        Map<String,String> userLoginInfo = new HashMap<>();
        userLoginInfo.put("loginName",loginName);
        userLoginInfo.put("loginPwd",loginPwd);
        return userLoginInfo;
    }
    /**
     *
     * @param userLoginInfo
     * @return boolean
     */
    private static boolean login(Map<String,String> userLoginInfo){
        //打标记
        boolean loginResult = false;
        /*
        P_JDBC_Test01.properties中的代码
        driver = com.mysql.jdbc.Driver
        url = jdbc:mysql://localhost:3306/bjpowernode
        user = root
        password = 020826
        */
        //JDBC代码
        Connection connection = null;
        Statement statement=null;
        ResultSet resultSet=null;
        ResourceBundle resourceBundle = ResourceBundle.getBundle("P_JDBC_Test01");
        String driver = resourceBundle.getString("driver");
        String url = resourceBundle.getString("url");
        String user = resourceBundle.getString("user");
        String password = resourceBundle.getString("password");
        try {
            //1. 注册驱动
            Class.forName(driver);
            //2. 获取连接
            connection = DriverManager.getConnection(url,user,password);
            //3. 获取数据操作对象
            statement = connection.createStatement();
            //4. 执行sql
           /* String sql = "select * from t_user where loginName = 'xxx' and loginPwd = ''";*/
            /*
            变量拼到一个字符串   重点
            loginName = '"+userLoginInfo.get("loginName")+"'
            */
            String sql = "select * from t_user where loginName = '"+userLoginInfo.get("loginName")+"' and loginPwd = '"+userLoginInfo.get("loginPwd")+"'";
            //上面这行进行了sql语句的拼接  下面这行发送sql语句到DBMS DBMS 进行sql 编译
            //正好将用户提供的非法信息编译进去 导致了原sql语句含义改变
            resultSet = statement.executeQuery(sql);
            //5. 处理查询结果集
            /* 这个例子中 用户不匹配查不到记录  用户匹配了也只能查到1条记录 所以不需要用while 用if就可与*/
            if (resultSet.next()){
                //如果为true 说明结果集中又数据 这个例子中 有数据代表用户匹配
                loginResult = true;
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            //6. 释放资源
            try {
                if (resultSet!=null){
                    resultSet.close();
                }
            }catch (Exception e){
                e.printStackTrace();
            }
            try {
                if (statement != null) {
                    statement.close();
                }
            }catch (Exception e){
                e.printStackTrace();
            }
            try {
                if (connection != null) {
                    connection.close();
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }
        return loginResult;
    }
}

上述案例存在sql注入现象

解决方法

使用java.sql.preparedStatement(预编译的数据库操作对象)

原理:

preparedStatement预先对sql语句进行了编译 然后再给SQL语句传"值"

用preparedStatement后第三步获取数据库操作对象和第四步执行sql会发生变化

//3. 获取预编译的数据操作对象
                //  ? 占位符 1个?将来会接收1个值
                //  SQL语句的框架
            String sql = "select * from t_user where loginName = ? and loginPwd = ? ";
                //程序执行到此会发送sql语句到DBMS 然后DBMS会进行sql语句的预编译
            /*prepareStatement 这个没有 d */
            preparedStatement = connection.prepareStatement(sql);
                //给 占位符 ? 传值 第一个 ? 下标是1 第二个是2  JDBC中下标从1开始
            preparedStatement.setString(1,userLoginInfo.get("loginName"));
            preparedStatement.setString(2,userLoginInfo.get("loginPwd"));
            //4. 执行sql
            resultSet = preparedStatement.executeQuery();

对比 Statement 和 preparedStatement

Statement 存在SQL注入问题

Statement 编译一次 执行一次

preparedStatement 编译一次 执行n次

preparedStatement大多情况使用 ,只有极少数情况使用Statement,当业务必须需要sql语句拼接 或sql注入的时候。

相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
21天前
|
SQL 安全 前端开发
Web学习_SQL注入_联合查询注入
联合查询注入是一种强大的SQL注入攻击方式,攻击者可以通过 `UNION`语句合并多个查询的结果,从而获取敏感信息。防御SQL注入需要多层次的措施,包括使用预处理语句和参数化查询、输入验证和过滤、最小权限原则、隐藏错误信息以及使用Web应用防火墙。通过这些措施,可以有效地提高Web应用程序的安全性,防止SQL注入攻击。
42 2
|
1月前
|
SQL Java 数据库连接
[SQL]SQL注入与SQL执行过程(基于JDBC)
本文介绍了SQL注入的概念及其危害,通过示例说明了恶意输入如何导致SQL语句异常执行。同时,详细解释了SQL语句的执行过程,并提出了使用PreparedStatement来防止SQL注入的方法。
41 1
|
2月前
|
SQL 存储 数据库
SQL学习一:ACID四个特性,CURD基本操作,常用关键字,常用聚合函数,五个约束,综合题
这篇文章是关于SQL基础知识的全面介绍,包括ACID特性、CURD操作、常用关键字、聚合函数、约束以及索引的创建和使用,并通过综合题目来巩固学习。
40 1
|
3月前
|
SQL 安全 数据库
惊!Python Web安全黑洞大曝光:SQL注入、XSS、CSRF,你中招了吗?
在数字化时代,Web应用的安全性至关重要。许多Python开发者在追求功能时,常忽视SQL注入、XSS和CSRF等安全威胁。本文将深入剖析这些风险并提供最佳实践:使用参数化查询预防SQL注入;通过HTML转义阻止XSS攻击;在表单中加入CSRF令牌增强安全性。遵循这些方法,可有效提升Web应用的安全防护水平,保护用户数据与隐私。安全需持续关注与改进,每个细节都至关重要。
140 5
|
3月前
|
SQL 安全 数据库
深度揭秘:Python Web安全攻防战,SQL注入、XSS、CSRF一网打尽!
在Web开发领域,Python虽强大灵活,却也面临着SQL注入、XSS与CSRF等安全威胁。本文将剖析这些常见攻击手段,并提供示例代码,展示如何利用参数化查询、HTML转义及CSRF令牌等技术构建坚固防线,确保Python Web应用的安全性。安全之路永无止境,唯有不断改进方能应对挑战。
75 5
|
3月前
|
SQL 安全 数据安全/隐私保护
Python Web安全大挑战:面对SQL注入、XSS、CSRF,你准备好了吗?
在构建Python Web应用时,安全性至关重要。本文通过三个真实案例,探讨了如何防范SQL注入、XSS和CSRF攻击。首先,通过参数化查询替代字符串拼接,防止SQL注入;其次,利用HTML转义机制,避免XSS攻击;最后,采用CSRF令牌验证,保护用户免受CSRF攻击。这些策略能显著增强应用的安全性,帮助开发者应对复杂的网络威胁。安全是一个持续的过程,需不断学习新知识以抵御不断变化的威胁。
126 1
|
3月前
|
SQL 安全 数据库
Python Web开发者必看!SQL注入、XSS、CSRF全面解析,守护你的网站安全!
在Python Web开发中,构建安全应用至关重要。本文通过问答形式,详细解析了三种常见Web安全威胁——SQL注入、XSS和CSRF,并提供了实用的防御策略及示例代码。针对SQL注入,建议使用参数化查询;对于XSS,需对输出进行HTML编码;而防范CSRF,则应利用CSRF令牌。通过这些措施,帮助开发者有效提升应用安全性,确保网站稳定运行。
51 1
|
3月前
|
SQL 安全 数据库
深度揭秘:Python Web安全攻防战,SQL注入、XSS、CSRF一网打尽!
在Web开发领域,Python虽强大灵活,但安全挑战不容小觑。本文剖析Python Web应用中的三大安全威胁:SQL注入、XSS及CSRF,并提供防御策略。通过示例代码展示如何利用参数化查询、HTML转义与CSRF令牌构建安全防线,助您打造更安全的应用。安全是一场持久战,需不断改进优化。
54 3
|
2月前
|
SQL 分布式计算 Java
大数据-96 Spark 集群 SparkSQL Scala编写SQL操作SparkSQL的数据源:JSON、CSV、JDBC、Hive
大数据-96 Spark 集群 SparkSQL Scala编写SQL操作SparkSQL的数据源:JSON、CSV、JDBC、Hive
47 0
|
2月前
|
SQL 分布式计算 关系型数据库
Hadoop-24 Sqoop迁移 MySQL到Hive 与 Hive到MySQL SQL生成数据 HDFS集群 Sqoop import jdbc ETL MapReduce
Hadoop-24 Sqoop迁移 MySQL到Hive 与 Hive到MySQL SQL生成数据 HDFS集群 Sqoop import jdbc ETL MapReduce
96 0