JDBC入门及SQL攻击解决

一:JDBC简介

我们学习了数据库,数据库实现了数据的持久化,但我们最终要在程序里处理数据啊,那java代码中怎么去访问数据库读写数据呢?这就要用到sun公司设定的一套数据库标准了,这套标准就是JDBC(Java Database Connectivity)。

但它只是规范,不做具体实现。于是数据库厂商又根据JDBC标准,实现自家的驱动Driver。如:mysql驱动com.mysql.cj.jdbc.Driver,Oracle的驱动oracle.jdbc.OracleDriver。有了这套解决方案,java就可以访问数据库中的数据了。

一句话概括:JDBC就是我们用IDEA连接数据库的工具,通过它可以实现在IDEA中对MYSQL进行增删改查的操作。

二:步骤

1.在idea中创建一个项目,并导入JDBCjar包

这里需要注意一点:你安装的哪个版本的 Mariadb 就需要安装对应版本的jar包(需要私我)

mariadbmysql
10.2/10.3/10.45.7
10.58.0

2.然后就可以开始写案例了.

package cn.tedu.review;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;

public class TestJdbc {
    public static void main(String[] args) throws Exception {
        Class.forName("com.mysql.cj.jdbc.Driver"); //注册驱动器
        String url ="jdbc:mysql://localhost:3306/cgb201901";//指定连接的数据库
                         //遵循的协议:IP地址:端口号 /数据库名
        String user="root";//用户名
        String pwd ="root";//密码
        Connection c = DriverManager.getConnection(url, user, pwd);//获取连接器
        Statement s = c.createStatement();//获取传输器
//s.executeUpdate("update emp set ename ='rousi' where emptno =1");//增删改用executeUpdate()方法,然后再查询
        ResultSet r = s.executeQuery("select * from emp");//查询使用executeQuery()
        while (r.next()){//此处调用r.next()方法:判断是否还有元素
            for (int i = 1; i <4 ; i++) {//利用for循环对结果进行遍历,表中有几列就遍历几次
                System.out.print(r.getObject(i));/*调用r.getObject方法可以获得数字,字符串所有类型的元素*/
            }
            System.out.println();
        }
        r.close();//关流
        s.close();
        c.close();
    }
}

前面的几步都比较固定,可以将其进行封装提高复用性。

三:JDBC模拟用户登录系统

1.在数据库中创建一个模拟用户资料的表格。

CREATE TABLE IF NOT EXISTS `user`(
`name` VARCHAR(20) NOT NULL COMMENT '姓名',
`password` VARCHAR(20) NOT NULL COMMENT '密码')
ENGINE=INNODB DEFAULT CHARSET=utf8;
INSERT INTO `user`(`name`,`password`) 
VALUE('jack',123456),('rousi',666666)

2.写JDBC代码
 

package cn.tedu.review;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Scanner;

public class TestJdbc {
    public static void main(String[] args) throws Exception {
        Class.forName("com.mysql.cj.jdbc.Driver");//注册驱动器
        String url ="jdbc:mysql://localhost:3306/cgb201901";//指定连接的数据库
                         //遵循的协议:IP地址:端口号 /数据库名
        String user="root";//用户名
        String pwd ="root";//密码
        Connection c = DriverManager.getConnection(url, user, pwd);//获取连接器
        Statement s = c.createStatement();//获取传输器
        System.out.println("请输入您的名字");
        String name = new Scanner(System.in).nextLine();
        System.out.println("请输入您的密码");
        String passWord = new Scanner(System.in).nextLine();
        String sql ="select * from user where name = '"+name+"'and passWord='"+passWord+"'";
        ResultSet r = s.executeQuery(sql);
        if (r.next()){//我们在数据库中查询数据,如果有证明账户存在,即登陆成功。
            System.out.println("恭喜您登陆成功");
        }else {
            System.out.println("登陆失败");
        }
        r.close();
        s.close();
        c.close();
    }
}

运行输入正确的账户密码提示登陆成功。

 3.SQL攻击(SQL注入)

虽然咱们登陆成功,但是存在一个很严重的bug。演示如下:

当我们在名字出输入:jack' # 后 系统也成功登陆,这就是SQL攻击(SQL注入)。 

原因:用户可以输入任意内容,而传输器只会单纯拼接内容,而无法识别特殊符号,致使MYSQL执行的时候也连同特殊符号一起执行,而#是注释,会注释掉后面所有内容。

解决方案:既然这个传输器不行,咱们就换一个传输器。

4.PreparedStatement 传输器

package cn.tedu.review;

import java.sql.*;
import java.util.Scanner;

public class TestJdbc1 {
    public static void main(String[] args) throws Exception {
        Class.forName("com.mysql.cj.jdbc.Driver");//注册驱动器
        String url ="jdbc:mysql://localhost:3306/cgb201901";//指定连接的数据库
        //遵循的协议:IP地址:端口号 /数据库名
        String user="root";//用户名
        String pwd ="root";//密码
        Connection c = DriverManager.getConnection(url, user, pwd);//获取连接器
        String  sql="select * from user where name = ?and passWord=?";//sql骨架,‘?’叫做占位符
        PreparedStatement p = c.prepareStatement(sql);//prepareStatement传输器的使用方法是需要sql语句参数
        System.out.println("请输入您的名字");
        String name = new Scanner(System.in).nextLine();
        System.out.println("请输入您的密码");
        String passWord = new Scanner(System.in).nextLine();
        p.setObject(1,name);//setObject()是给对应下标占位符赋予数值
        p.setObject(2,passWord);
        ResultSet r = p.executeQuery();
        if (r.next()){
            System.out.println("恭喜您登陆成功");
        }else {
            System.out.println("登陆失败");
        }
        r.close();
        p.close();
        c.close();
    }
}

结果就是我们解决了sql攻击问题,再次输入注释符#已经不起作用了。

原理:我们使用prepareStatement传输器,在sql语句中用占位符‘?’提前预定了name和password的位置,输入的内容就会判定为name 和password 的内容,不再进行拼接。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值