JDBC小记——SQL注入及预编译操作对象、批处理

目录

SQL注入

预编译操作对象

自定义JDBC工具类

1.创建配置文件

2.配置

3.在工具类中使用配置文件

批处理

注意事项


SQL注入

SQL注入是黑客对数据库进行攻击的常用手段之一,他们拼接一些恶意的sql语句,来获取他们想要的数据。

例:

select * from user where username='1' or '1'='1' and password='1' or '1' = '1';

利用sql语言的特点,即where后面的条件为真,来恶意查询数据,即可查询到全部数据

JDBC小记——SQL注入及预编译操作对象、批处理_第1张图片

JDBC小记——SQL注入及预编译操作对象、批处理_第2张图片

 为了解决这个问题,我们要用到预编译操作对象,防止sql注入

预编译操作对象

PreparedStatement     用来防止SQL注入

//SQL语句中的值 全部用 ? 问号占位

String sql = "select * from user where username=? and password=?";

//获取一个预编译操作对象  PreparedStatement

PreparedStatement preparedStatement = conn.prepareStatement(sql);

//给问号赋值

preparedStatement.setString(1, uname);
preparedStatement.setString(2, pwd);

ResultSet resultSet = preparedStatement.executeQuery(); //不用传sql

其他代码都与之前一致

JDBC小记——SQL注入及预编译操作对象、批处理_第3张图片

执行程序后,没有查询到任何数据。

就是因为我们使用了预编译操作对象——preparedStatement

他的setString()方法中对非法单引号做了转义,使得坏人不能够得逞。

我们可以打印看一下

JDBC小记——SQL注入及预编译操作对象、批处理_第4张图片

自定义JDBC工具类

首先建一个工具包,在里面定义JBDC工具类

JDBC小记——SQL注入及预编译操作对象、批处理_第5张图片

JDBC小记——SQL注入及预编译操作对象、批处理_第6张图片

但是,数据库、用户名和密码总不是固定不变的,当我们需要去改变时,需要打开这个工具类来改变数据,不如我们创建一个配置文件,使用配置文件来读取数据、修改数据来的方便。

1.创建配置文件

JDBC小记——SQL注入及预编译操作对象、批处理_第7张图片

JDBC小记——SQL注入及预编译操作对象、批处理_第8张图片

2.配置

JDBC小记——SQL注入及预编译操作对象、批处理_第9张图片

3.在工具类中使用配置文件

JDBC小记——SQL注入及预编译操作对象、批处理_第10张图片

批处理

即多条sql语句一起执行,当插入大量数据时,建议使用批处理。

statement.addBatch();//添加批处理,先将数据缓存起来
statement.executeBatch();//执行批处理
statement.clearBatch();//清空缓存

如果我们向数据库中一条条插入数据,如下:

package org.xingyun.demo;

import org.xingyun.bean.Bank;
import org.xingyun.utils.JDBCUtil;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.ArrayList;

public class demo5 {
    public static void main(String[] args) throws SQLException {
        ArrayList list = new ArrayList<>();
        for (int i = 0; i < 50000; i++) {
            Bank bank = new Bank(1010+i,"zhangsan"+i,1000+i);
            list.add(bank);
        }
        Connection conn = JDBCUtil.getConnection();
        String sql="insert into bank(id, username, money) values (?,?,?)";
        PreparedStatement preparedStatement = conn.prepareStatement(sql);
        long l = System.currentTimeMillis();
        for (Bank bank : list) {
            preparedStatement.setInt(1,bank.getId());
            preparedStatement.setString(2, bank.getUsername());
            preparedStatement.setInt(3, bank.getMoney());
            preparedStatement.executeUpdate();
        }
        long ll = System.currentTimeMillis();
        System.out.println(ll-l);
        JDBCUtil.close(conn,preparedStatement);

    }
}

所用时间为:30322ms

JDBC小记——SQL注入及预编译操作对象、批处理_第11张图片

sql语句是一条一条执行,则效率会非常低。

当需要插入大量数据时,我们使用批处理,就是sql语句多条执行,则效率会非常高。如下:

package org.xingyun.demo;

import org.xingyun.bean.Bank;
import org.xingyun.utils.JDBCUtil;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.ArrayList;

public class demo6 {
    public static void main(String[] args) throws SQLException {
        ArrayList list = new ArrayList<>();
        for (int i = 0; i < 5000; i++) {
            Bank bank = new Bank(1010 + i, "zhangsan" + i, 1000 + i);
            list.add(bank);
        }

        Connection conn = JDBCUtil.getConnection();
        String sql = "insert into bank(id, username, money) values (?,?,?)";
        PreparedStatement preparedStatement = conn.prepareStatement(sql);
        long l = System.currentTimeMillis();
        for (Bank bank : list) {
            preparedStatement.setInt(1, bank.getId());
            preparedStatement.setString(2, bank.getUsername());
            preparedStatement.setInt(3, bank.getMoney());
            preparedStatement.addBatch();
        }
        preparedStatement.executeBatch();
        preparedStatement.clearBatch();
        long ll = System.currentTimeMillis();
        System.out.println(ll-l);
        JDBCUtil.close(conn, preparedStatement);

    }
}

所用时间为:6196

由此可见,时间缩短为不使用批处理时的五分之一。

可见,效率很高。

注意事项

但 提交的sql不能超过max_allowed_packet的设置值 不然报错

jdbc:mysql://localhost:3306/shopxxb2b2c?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=UTF-8&useSSL=false&rewriteBatchedStatements=true

max_allowed_packet查询方法
进入mysql容器 运行

show VARIABLES like 'max_allowed_packet';
1
mysql> show VARIABLES like 'max_allowed_packet';
+--------------------+------------+
| Variable_name      | Value      |
+--------------------+------------+
| max_allowed_packet | 1073741824 |
+--------------------+------------+
1 row in set
max_allowed_packet的单位为字节:

-- 转化为Mb,就是1024Mb
mysql> select 1073741824/1024/1024;
+----------------------+
| 1073741824/1024/1024 |
+----------------------+
| 1024.00000000        |
+----------------------+
1 row in set
————————————————

你可能感兴趣的:(JDBC,sql,数据库,java,mysql)