1、JDBC入门、Statement及SQL注入、PreparedStatement及如何解决SQL注入

JDBC

HelloWorld

package org.westos.demo;

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

/**
 * @author lwj
 * @date 2020/8/11 9:02
 */
public class MyTest {
    public static void main(String[] args) throws ClassNotFoundException, SQLException {
        /*
        JDBC:Java DataBase Connection
        Java连接数据库
        由Java定义一套操作数据库的接口/规范(java.sql、javax.sql),由各个数据库厂商来实现这些接口(这些实现类称为数据库驱动),
        我们只需要在代码中引入对应数据库的驱动即可。
         */
        /*
        JDBC入门:
        1、导入数据库驱动(jar包); https://mvnrepository.com/artifact/mysql/mysql-connector-java/5.1.47 在maven中下载jar包
            项目中新建lib目录,引入jar包,导入依赖Add as library
        2、加载驱动;
        3、获取连接对象Connection;
        4、获取操作对象Statement;
        5、执行SQL;
        6、释放资源
         */
        Class.forName("com.mysql.jdbc.Driver");
        //加载驱动
        String url = "jdbc:mysql://localhost:3306/jdbc?useSSL=false";
        String username = "root";
        String password = "xxxxxx";
        Connection connection = DriverManager.getConnection(url, username, password);
        //获取连接对象
        Statement statement = connection.createStatement();
        //获取操作对象
        //定义SQL语句
        String sql = "insert into users values(null, '张三', '123456', '1999-09-09')";
        int i = statement.executeUpdate(sql);
        //返回受影响的行数
        System.out.println(i);
        //1
        statement.close();
        connection.close();
        //释放资源
    }
}

1、准备数据库环境

CREATE DATABASE jdbc;

CREATE TABLE IF NOT EXISTS users(
	id INT NOT NULL AUTO_INCREMENT,
	username VARCHAR(20) NOT NULL,
	PASSWORD VARCHAR(20) NOT NULL,
	birthday DATE NOT NULL,
	PRIMARY KEY(id)
);

2、找jdbc jar包的方法

https://mvnrepository.com/artifact/mysql/mysql-connector-java

根据数据库版本选择不同的jar包版本

在这里插入图片描述

3、在IDEA中配置MySQL连接,绑定之后写SQL语句会有提示
在这里插入图片描述
4、配置项目中sql字符串的类型为MySQL代码

5、查看代码执行结果
在这里插入图片描述

加载驱动

package org.westos.demo;


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

/**
 * @author lwj
 * @date 2020/8/11 9:58
 */
public class MyTest2 {
    public static void main(String[] args) throws ClassNotFoundException, SQLException {
        Class.forName("com.mysql.jdbc.Driver");
        //加载驱动,Driver类的静态代码块已经新建了驱动对象,并且注册到DriverManager类中
        /*
        public class Driver extends NonRegisteringDriver implements java.sql.Driver {
            public Driver() throws SQLException {
            }

            static {
                try {
                    DriverManager.registerDriver(new Driver());
                } catch (SQLException var1) {
                    throw new RuntimeException("Can't register driver!");
                }
            }
        }
         */
        String url = "jdbc:mysql://localhost:3306/jdbc?useSSL=false";
        // jdbc协议格式

        String username = "root";
        String password = "xxxxxx";
        Connection conn = DriverManager.getConnection(url, username, password);
        //DriverManager:驱动管理类,getConnection()返回java.sql.Connection接口的实现类
        System.out.println(conn);
        //com.mysql.jdbc.JDBC4Connection@25f38edc

        Statement statement = conn.createStatement();
        System.out.println(statement);
        //获取操作对象,com.mysql.jdbc.StatementImpl@1a86f2f1

        String sql = "update users set birthday = '1999-10-10' where id = 1";
        int i = statement.executeUpdate(sql);
        //executeUpdate()对应sql中的增删改语句,返回的是int类型,受影响的行数
        System.out.println(i);
        //1

        statement.close();
        conn.close();
        //释放资源
    }
}

查询语句

1、准备实体类user

package org.westos.bean;

import java.util.Date;

/**
 * @author lwj
 * @date 2020/8/11 10:38
 * 实体类中的属性名、类型和表中的字段名、类型保持一致
 */
public class User {
    private int id;
    private String username;
    private String password;
    private Date birthday;
    //java.util.Date


    public User() {
    }

    public User(int id, String username, String password, Date birthday) {
        this.id = id;
        this.username = username;
        this.password = password;
        this.birthday = birthday;
    }

    //getter()、setter()、toString()
}

2、JDBC查询数据库

package org.westos.demo;

import org.westos.bean.User;

import java.sql.*;
import java.util.ArrayList;

/**
 * @author lwj
 * @date 2020/8/11 10:27
 */
public class MyTest3 {
    public static void main(String[] args) throws ClassNotFoundException, SQLException {
        Class.forName("com.mysql.jdbc.Driver");
        Connection conn = DriverManager.getConnection("jdbc:mysql:///jdbc?useSSL=false", "root", "xxxxxx");
        Statement statement = conn.createStatement();
        String sql = "select id, username, password, birthday from users";
        ResultSet resultSet = statement.executeQuery(sql);
        ArrayList<User> users = new ArrayList<>();
        //返回结果集
        while (resultSet.next()) {
            int id = resultSet.getInt("id");
            //根据columnLabel字段别名获取
            String username = resultSet.getString("username");
            String password = resultSet.getString(3);
            //根据columnIndex获取
            Date birthday = resultSet.getDate("birthday");
            //返回java.sql.Date类型,并不是SE阶段的java.util.Date

            Date date_birthday = new Date(birthday.getTime());
            User user = new User();
            user.setId(id);
            user.setUsername(username);
            user.setPassword(password);
            user.setBirthday(date_birthday);
            users.add(user);
        }
        //遍历集合
        users.forEach(System.out::println);
        /*
        User{id=1, username='张三', password='123456', birthday=1999-10-10}
        User{id=2, username='李四', password='123456', birthday=1999-09-09}
        User{id=3, username='王五', password='123456', birthday=1999-09-09}
         */
        resultSet.close();
        statement.close();
        conn.close();
    }
}

Statement及其弊端

  • 用于向数据库发送SQL语句,完成增删改查操作
  • executeUpdate(sql),对应增删改DML,返回表中受影响的行数
  • executeQuery(sql),对应查询语句DQL,返回查询出来的结果集,用ResultSet对象接收
  • next()遍历ResultSet
package org.westos.demo;

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

/**
 * @author lwj
 * @date 2020/8/11 11:11
 */
public class MyTest4 {
    public static void main(String[] args) throws ClassNotFoundException, SQLException {
        //模拟登陆,引入PreparedStatement
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入用户名:");
        String username = sc.nextLine();
        System.out.println("请输入密码:");
        String password = sc.nextLine();

        Class.forName("com.mysql.jdbc.Driver");
        Connection conn = DriverManager.getConnection("jdbc:mysql:///jdbc?useSSL=false", "root", "xxxxxx");
        Statement statement = conn.createStatement();
        String sql = "select * from users where username = '" + username + "' and password = '" + password + "'";
        //拼sql串
        ResultSet resultSet = statement.executeQuery(sql);
        if (resultSet.next()) {
            System.out.println("登陆成功");
        } else {
            System.out.println("登陆失败");
        }
    }
}
SELECT * FROM users WHERE username = '张三' AND PASSWORD = '123456';
/*
id	username	password	birthday
1	张三			123456		1999-10-10
*/

在这里插入图片描述

SQL注入

-- SQL注入(手动拼接sql)
SELECT * FROM users WHERE username = 'xxx' AND PASSWORD = 'xxxxxx' OR '1' = '1';
/*
id	username	password	birthday
1	张三			123456		1999-10-10
2	李四			123456		1999-09-09
3	王五			123456		1999-09-09
*/

在这里插入图片描述

PreparedStatement

package org.westos.demo;

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

/**
 * @author lwj
 * @date 2020/8/11 11:38
 */
public class MyTest5 {
    public static void main(String[] args) throws ClassNotFoundException, SQLException {
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入用户名:");
        String username = scanner.nextLine();
        System.out.println("请输入密码:");
        String password = scanner.nextLine();

        Class.forName("com.mysql.jdbc.Driver");
        Connection conn = DriverManager.getConnection("jdbc:mysql:///jdbc?useSSL=false", "root", "xxxxxx");
        String sql = "select * from users where username = ? and password = ?";
        PreparedStatement preparedStatement = conn.prepareStatement(sql);
        // PreparedStatement预编译操作对象,防止SQL注入
        preparedStatement.setString(1, username);
        preparedStatement.setString(2, password);
        //对SQL中的参数进行赋值
        System.out.println(preparedStatement.toString());
        ResultSet resultSet = preparedStatement.executeQuery();
        if (resultSet.next()) {
            System.out.println("登陆成功");
        } else {
            System.out.println("登陆失败");
        }
        resultSet.close();
        preparedStatement.close();
        conn.close();
    }
}

在这里插入图片描述
在这里插入图片描述

SELECT * FROM users WHERE username = 'xxx' AND PASSWORD = 'xxx\' or \'1\' = \'1';

PreparedStatement的巧妙之处在于:(setString填充参数时),两端加单引号,将参数内的一些特殊字符(换行,单双引号,斜杠等)做转义处理,这样就很大限度的避免了sql注入。

当填充参数为int类型时,

package org.westos.demo;

import java.sql.*;

/**
 * @author lwj
 * @date 2020/8/11 12:11
 */
public class MyTest6 {
    public static void main(String[] args) throws ClassNotFoundException, SQLException {
        Class.forName("com.mysql.jdbc.Driver");
        Connection conn = DriverManager.getConnection("jdbc:mysql:///jdbc?useSSL=false", "root", "xxxxxx");
        String sql = "select * from users where id = ?";
        PreparedStatement preparedStatement = conn.prepareStatement(sql);
        preparedStatement.setInt(1, 1);
        System.out.println(preparedStatement.toString());
        //com.mysql.jdbc.JDBC42PreparedStatement@42110406: select * from users where id = 1
        ResultSet resultSet = preparedStatement.executeQuery();
        while (resultSet.next()) {
            System.out.println(resultSet.getString("username"));
            //张三
        }
        resultSet.close();
        preparedStatement.close();
        conn.close();
    }
}

猜你喜欢

转载自blog.csdn.net/ShawnYue_08/article/details/107932753
今日推荐