SQL操作的封装,statement与PreparedStatement的区别,SQL注入

JDBC

1.数据库驱动

应用程序和数据库无法直接挂钩,所以就需要一个驱动。这个驱动是由数据库厂商提供的。

每个数据库都有一个对应的驱动。

2.JDBC

SUN公司为了简化数据的操作,提供了一个规范,俗称jdbc。

jdbc是驱动和驱动之间的部分。这里用5.1.47的驱动版本。

https://www.mvnjar.com/mysql/mysql-connector-java/5.1.47/detail.html
SQL操作的封装,statement与PreparedStatement的区别,SQL注入

3.第一个JDBC

问题

  1. 创建bin包,导入jar包,右键添加到库中、
  2. 首先创建一个数据库,并且创建一个表插入一些数据

链接数据库步骤:

  1. 加载驱动
  2. 用户信息和数据库url(三个参数来避免奇怪的异常)
  3. 连接成功,返还数据库对象
  4. 执行SQL对象
  5. 执行SQL的对象,去执行SQL,可能存在结果(返回结果集)
  6. 释放连接

问题:

SQL操作的封装,statement与PreparedStatement的区别,SQL注入

原因:连接数据库的顺序必须是url,user,password。顺序反了不可以。

package JDBCTest;
import java.sql.*;
public class JdbcDemo01 {
    public static void main(String[] args) throws ClassNotFoundException, SQLException {
        //1.加载数据库驱动
        Class.forName ("com.mysql.jdbc.Driver");
        //2.用户名,地址,密码
        String user = "root";
        String password = "123456";
        String url = "jdbc:mysql://localhost:3306/school?useUnicode=true&characterEncoding=utf8&useSSL=true";
        //3.获取数据库连接
        Connection connection = DriverManager.getConnection (url,user,password);
        //4.获取sql语句对象
        Statement statement = connection.createStatement ();
        //5。使用的sql语句
        String sql = "select * from studentInfo";
        //6.执行SQL语句,获取结果集
        ResultSet resultSet = statement.executeQuery (sql);
        while (resultSet.next ()){
            System.out.println ("学生的id"+resultSet.getObject ("id"));
            System.out.println ("学生的姓名"+resultSet.getObject ("name"));
            System.out.println ("学生的号码"+resultSet.getObject ("phoneNum"));
            System.out.println ("学生的地址"+resultSet.getObject ("address"));
        }
        connection.close ();
        statement.close ();
        resultSet.close ();
    }
}

connection对象可以执行很多操作。

statement执行sql对象。

ResultSet只有查询才有。ResultSet.beforeFirst();ResultSet.afterLast();移动迭代时候的光标

statement对象

问题:

  1. statement的作用?
  2. 它的方法有哪些
  3. 数据库解耦操作?工具类&配置properties

1.配置db.properties。在文件最底层目录下

driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/school?useUnicode=true&characterEncoding=utf8&useSSL=true
username=root
password=123456

2.设置Utils包设置JdbcUtils类来解耦。封装,插入,删除,更新等算法

package JDBCTest.utils;

import java.io.IOException;
import java.io.InputStream;
import java.sql.*;
import java.util.Properties;

public class JdbcUtils {
    private static String driver = null;
    private static String url = null;
    private static String username = null;
    private static String password = null;
    static {
        try{
            InputStream in = JdbcUtils.class.getClassLoader ().getResourceAsStream ("db.properties");
            Properties properties = new Properties ();
            properties.load (in);

            driver = properties.getProperty ("driver");
            url = properties.getProperty ("url");
            username = properties.getProperty ("username");
            password = properties.getProperty ("password");

            Class.forName (driver);
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace ();
        }
    }
    //获取连接
    public static Connection getConnection() throws SQLException {
        return DriverManager.getConnection (url,username,password);
    }
    //释放资源
    public static void release(Connection connection, Statement statement, ResultSet resultSet){
        if(resultSet!=null){
            try {
                resultSet.close ();
            } catch (SQLException e) {
                e.printStackTrace ();
            }
        }
        if(statement!=null){
            try {
                statement.close ();
            } catch (SQLException e) {
                e.printStackTrace ();
            }
        }
        if(connection!=null){
            try {
                connection.close ();
            } catch (SQLException e) {
                e.printStackTrace ();
            }
        }

    }
}

封装删除语句

package JDBCTest.utils;

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

public class TestDelete {
    public static void main(String[] args) {
        Connection connection = null;
        Statement statement = null;
        ResultSet resultSet = null ;
        try{
            connection = JdbcUtils.getConnection ();
            statement=connection.createStatement ();
            String sql =" DELETE FROM `school`.`studentinfo` WHERE `id` = ‘100001‘";
            int i = statement.executeUpdate (sql);
            if (i>0){
                System.out.println ("删除成功!");
            }
        } catch (SQLException e) {
            e.printStackTrace ();
        }finally {
            JdbcUtils.release (connection,statement,resultSet);
        }


    }
}

封装插入语句

public static void main(String[] args) {
    Connection connection = null;
    Statement statement = null;
    ResultSet resultSet = null ;
    try{
        connection = JdbcUtils.getConnection ();
        statement=connection.createStatement ();
        String sql ="INSERT INTO `school`.`studentinfo` (`id`, `name`, `phoneNum`, `address`) VALUES (‘10002‘, ‘BigFace‘, ‘10000‘, ‘安徽六安‘)";
        int i = statement.executeUpdate (sql);
        if (i>0){
            System.out.println ("插入成功!");
        }
    } catch (SQLException e) {
        e.printStackTrace ();
    }finally {
        JdbcUtils.release (connection,statement,resultSet);
    }
}

封装更新语句

package JDBCTest.utils;

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

public class TestUpdate {
    public static void main(String[] args) {
        Connection connection = null;
        Statement statement = null;
        ResultSet resultSet = null;
        try{
            connection = JdbcUtils.getConnection ();
            statement =connection.createStatement ();
            String sql = "UPDATE `school`.`studentinfo` SET `phoneNum` = ‘10010‘ WHERE `id` = ‘10002‘ ";
            int i = statement.executeUpdate (sql);
            if (i>0){
                System.out.println ("更新数据成功!");
            }
        } catch (SQLException e) {
            e.printStackTrace ();
        }finally {
            JdbcUtils.release (connection,statement,resultSet);
        }
    }
}

SQL注入

利用字符串拼接,来获取数据库全部输入而绕过登录

https://baike.baidu.com/item/sql%E6%B3%A8%E5%85%A5/150289?fr=aladdin

package JDBCTest.utils;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class SqlInjectionAttack {
    public static void login(String username,String password){
        Connection connection = null;
        Statement statement = null;
        ResultSet resultSet = null ;
        try{
            connection = JdbcUtils.getConnection ();
            statement=connection.createStatement ();
            //  SELECT * FROM `studentinfo` WHERE `name`=‘李欢欢‘ AND `phoneNum`=10086

            String sql ="SELECT * FROM `studentinfo` WHERE `name`=‘"+username+"‘ AND `password`=‘"+password+"‘";
            resultSet=statement.executeQuery (sql);
            while (resultSet.next ()){
                System.out.println (resultSet.getString ("name"));
                System.out.println (resultSet.getString ("password"));
            }
        } catch (SQLException e) {
            e.printStackTrace ();
        }finally {
            JdbcUtils.release (connection,statement,resultSet);
        }

    }
    public static void main(String[] args) {
       // login("李欢欢","10000");
      //  SELECT * FROM `studentinfo` WHERE `name`=‘李欢欢‘ or ‘1=1‘  AND `password=10000
        login (" ‘or ‘1=1"," ‘or‘1=1");
    }
}

PreparedStatement对象

  1. 预编译SQL语句
  2. Java date类转换成mysql date类
  3. 避免SQL注入
  4. 当复习到这里的时候,重写一个更新语句!!!!

优点:避免了SQL注入攻击,效率更高,更安全

重写了删除语句

package JDBCTest;

import JDBCTest.utils.JdbcUtils;

import java.sql.*;

public class TestDelete1 {
    public static void main(String[] args) {
        Connection connection = null;
        PreparedStatement preparedStatement = null;
        try{//使用preparedStatement重写
            //1.获取数据库连接
            connection = JdbcUtils.getConnection ();
            //2.编译sql语句,使用占位符
            String sql = " DELETE FROM `school`.`studentinfo` WHERE `id` = ?";
            //3.获取PreparedStatement对象,预编译sql
            preparedStatement = connection.prepareStatement (sql);
            //4.手动设置值
            preparedStatement.setInt (1,10000);
            //5。执行sql
            int i = preparedStatement.executeUpdate ();
            if (i>0){
                System.out.println ("删除成功!");
            }
        } catch (SQLException e) {
            e.printStackTrace ();
        }finally {
            JdbcUtils.release (connection,preparedStatement,null);
        }
    }
}

重写了插入语句

package JDBCTest;

import JDBCTest.utils.JdbcUtils;

import java.sql.*;

public class TestInsert1 {
    public static void main(String[] args) {
        Connection connection = null;
        PreparedStatement preparedStatement = null;
        try{
            connection = JdbcUtils.getConnection ();
            //1.获取sql语句
            String sql ="INSERT INTO `school`.`studentinfo` (`id`, `name`, `phoneNum`, `address`,`password`) VALUES (?,?,?,?,?)";
            //2.预编译sql
            preparedStatement = connection.prepareStatement (sql);
            //3.手动设置值
            preparedStatement.setInt (1,10099);
            preparedStatement.setString (2,"dashadan");
            preparedStatement.setString (3,"19880281");
            preparedStatement.setString (4,"北京市");
            preparedStatement.setString (5,"Jhj1000");
            //执行sql语句
            int i = preparedStatement.executeUpdate ();
            if (i>0){
                System.out.println ("插入成功!");
            }
        } catch (SQLException e) {
            e.printStackTrace ();
        }finally {
            JdbcUtils.release (connection,preparedStatement,null);
        }
    }
}

SQL操作的封装,statement与PreparedStatement的区别,SQL注入

上一篇:数据库-Sqlite值JOIN


下一篇:JDBCToolsV3