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后面的条件为真,来恶意查询数据,即可查询到全部数据

 为了解决这个问题,我们要用到预编译操作对象,防止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

其他代码都与之前一致

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

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

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

我们可以打印看一下

自定义JDBC工具类

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

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

1.创建配置文件

2.配置

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

批处理

即多条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<Bank> 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

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<Bank> 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
————————————————

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Jmh-Ethereal

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值