JDBC (介绍+实例:防SQL注入)

JDBC

Java DataBase Connectivity 是一个独立于特定数据库的管理系统,通用的SQL数据库存储和操作的公共接口。
定义了一组标准,为访问不同数据库提供了统一的途径

JDBC体系结构

JDBC接口包含两个层面:

  • 面向应用的API,供程序员调用
  • 面向数据的API,供厂商开发数据库的驱动程序

在这里插入图片描述

  1. JDBC API
    提供者: JAVA官方
    内容:供开发者调用的接口

     - java.sql 和 javax.sql
     - DriverManager 类
     -  Connection接口
     - Statement接口
     - ResultSet 接口
    
  2. JDBC Driver Manger
    提供者:Java官方
    作用:管理不同的JDBC驱动

  3. JDBC驱动
    提供者:数据库厂商
    作用:负责连接不同的数据库

JDBC的使用

1、加载数据库驱动,java程序和数据库之间的桥梁
2、获取Connection,java程序与数据库的一次连接。
3、创建Statement对象,由Connection产生,执行SQL语句
4、如果需要接收返回值,创建ResultSet对象,保存Statement执行查询到的结果(查询才需要ResultSet对象)

  public static void main(String[] args) {

        try {
            //加载驱动
            Class.forName("com.mysql.cj.jdbc.Driver");
            //获取连接,此处包含SSL和时区设置
            String url = "jdbc:mysql://localhost:3306/mytest?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=UTC";
            String user= "root";
            String password = "1234567";
            Connection connection = DriverManager.getConnection(url,user,password);//url提供服务器、端口、数据库;user提供账号,password提供密码
            System.out.println(connection);//打印出连接对象
            String sql = "insert into student( name ,score,birthday) values('王五',60,'2019-01-11')";//添加操作
//            sql = "delete from student";//删除操作
//            sql = "update student set name = '李四'";//更新操作
            Statement statement = connection.createStatement();//相当于通道语句
            int result = statement.executeUpdate(sql);//增删改的执行语句
            System.out.println(result);//返回修改的语句数量

//            String sql = "select * from student";//查询操作
//            Statement statement = connection.createStatement();//通道语句
//            ResultSet resultSet = statement.executeQuery(sql);//查询所需的结果集
//            while(resultSet.next())//循环输出
//            {
// //               Integer id = resultSet.getInt("id");
//                String name = resultSet.getString(1);
//                Double score = resultSet.getDouble(2);
//                Date date=  resultSet.getDate(3);
//                System.out.println("-"+name+"-"+score+"-"+date);
//            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }catch (SQLException e)
        {
            e.printStackTrace();
        }
    }
}

PreparedStatement

Statement 的子类,提供了SQL占位符的功能
使用Statement进行开发的两个问题:
1、需要频繁拼接String字符串,出错率较高。
2、存在SQL注入的风险

SQL注入:利用某些系统没有对用户输入的信息进行充分检测,在用户输入的数据中注入非法的SQL语句,从而利用系统的SQL引擎完成恶意行为的做法。

非法例子:

public class test {
    public static void main(String[] args) {

        try {
            //加载驱动
            Class.forName("com.mysql.cj.jdbc.Driver");
            //获取连接,此处包含SSL和时区设置
            String url = "jdbc:mysql://localhost:3306/mytest?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=UTC";
            String user= "root";
            String password = "1234567";
            Connection connection = DriverManager.getConnection(url,user,password);//url提供服务器、端口、数据库;user提供账号,password提供密码
            System.out.println(connection);//打印出连接对象
            String username = "李四";//
            String mypassword = "xxxx' or  '1'='1"; //最左补个‘,最后补个’  形成非法语句
            String sql = "select * from t_user where username ='"+username+ "' and password='"+mypassword+"'";
            System.out.println(sql);
            Statement statement = connection.createStatement();
            ResultSet resultSet = statement.executeQuery(sql);
            if(resultSet.next())
            {
                System.out.println("登陆成功");
            }else{
                System.out.println("登陆失败");
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }catch (SQLException e)
        {
            e.printStackTrace();
        }
    }
}

非法语句构成结果:

在这里插入图片描述

正确做法(PreparedStatement 提供占位符)

public class test {
    public static void main(String[] args) {

        try {
            //加载驱动
            Class.forName("com.mysql.cj.jdbc.Driver");
            //获取连接,此处包含SSL和时区设置
            String url = "jdbc:mysql://localhost:3306/mytest?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=UTC";
            String user= "root";
            String password = "1234567";
            Connection connection = DriverManager.getConnection(url,user,password);//url提供服务器、端口、数据库;user提供账号,password提供密码
            System.out.println(connection);//打印出连接对象
            String username = "李四";//
            String mypassword = "xxxx' or  '1'='1";
            String sql = "select * from t_user where username = ? and password= ? ";
            System.out.println(sql);
//            Statement statement = connection.createStatement();
            PreparedStatement preparedStatement = connection.prepareStatement(sql);
            preparedStatement.setString(1,username);
            preparedStatement.setString(2,mypassword);
//            ResultSet resultSet = statement.executeQuery(sql);
            ResultSet resultSet = preparedStatement.executeQuery();
            if(resultSet.next())
            {
                System.out.println("登陆成功");
            }else{
                System.out.println("登陆失败");
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }catch (SQLException e)
        {
            e.printStackTrace();
        }
    }
}

正确结果

在这里插入图片描述

本素材来源于网上视频 + 手动操作,仅用于个人记录,如有侵权,请联系删除

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值