【Java】JDBC Part3 大文件操作和批量操作的实现

2020-04-24 16:19:37 蜻蜓队长

 

- PreparedStatement还可以操作大数据类型的数据,Statement不行

- PreparedStatement可实现批量操作

 

User表新加一个MediumBlob数据类型,存储大型文件

 

- TinyBlob  255b 字节

- Blob  65kb

- MediumBlob  16mb

- LongBlob  4gb

 

使用我们的JDBC执行插入SQL

注意如果手动注入参数,字段的索引从1开始

输入流对象读取文件的位置

 

    @Test
    public void blobTest() throws FileNotFoundException {
        
        // 插入 、删除、修改、是一样的
        String sql = "insert into user(user_name,user_password,user_img) values(?,?,?);";

        InputStream inputStream = new FileInputStream(new File("1.jpg"));

        Object[] args = new Object[]{"废品同调士","333666",inputStream};

        // preparedStatement = setBlob(column,inputStream);

        JdbcUtil.update(sql,args);
    }

 

 

执行查询操作

    @Test
    public void blobTest2() throws Exception {
        Connection connection = JdbcUtil.getConnection();
        String sql = "Select * from user where user_id = 6";
        PreparedStatement preparedStatement = connection.prepareStatement(sql);
        ResultSet resultSet = preparedStatement.executeQuery();

        User user = new User();
        InputStream binaryStream = null;

        // 因为只有一个记录,所以不用循环了
        if (resultSet.next()){
            user.setUser_id( (Integer) resultSet.getObject(1) );
            user.setUser_name( (String) resultSet.getObject(2) );
            user.setUser_password( (String) resultSet.getObject(3) );

            Blob blob = resultSet.getBlob(5); // 返回Blob 大文件对象
            binaryStream = blob.getBinaryStream(); // Blob对象返回一个二进制流对象 
            System.out.println(user);
        }

        OutputStream outputStream = new FileOutputStream("2.jpg"); //创建输出流对象

        byte[] bytesBuffer = new byte[1024]; // 缓冲数组
        int len;
        while ( (len = binaryStream.read(bytesBuffer)) != -1 ){
            outputStream.write(bytesBuffer,0,len); // 输出写入
        }

        resultSet.close();
        JdbcUtil.closeResource(connection,preparedStatement);
    }

 

图片也读取出来了

 

如果是插入超过2M大小的图片可能报异常错误了

但是我测试的添加和查询的结果没有报错,演示不了错误异常

 

我这里直接Eclipse的报错异常好了

文件过大异常

 

处理方法也很简单:

修改最大可存储字节  max_allowed_packet=16M

8.0貌似默认4M,但是我6M的图片上传读取都没问题。。。

保存修改之后重启MySQL的服务

再执行一遍就可以了

 


 

PreparedStatement实现批量操作

- 批量插入

    @Test
    public void blobTest3() throws FileNotFoundException, SQLException {
        // 批量插入
        String sql = "insert into user(user_name,user_password) values(?,?);";
        // 预编译SQL对象执行后保留有SQL缓存,多次注入只需要参数即可,
        Connection connection = JdbcUtil.getConnection();
        PreparedStatement preparedStatement = connection.prepareStatement(sql);
        for (int i = 0; i < 100 ; i++) {
            preparedStatement.setObject(1,"演示批量操作"+i);
            preparedStatement.setObject(2,"123"+i);
            preparedStatement.execute();
        }
        JdbcUtil.closeResource(connection,preparedStatement);
    }

 

- 批量操作2

    @Test
    public void blobTest3() throws SQLException {
        String sql = "insert into user(user_name,user_password) values(?,?)"; //批量操作不要在SQL语句加冒号结束
        Connection connection = JdbcUtil.getConnection();
        PreparedStatement preparedStatement = connection.prepareStatement(sql);
        for (int i = 0; i < 100 ; i++) {
            // addBatch(),executeBatch(),clearBatch();
            preparedStatement.setObject(1,"演示批量操作"+i);
            preparedStatement.setObject(2,"123"+i);

            preparedStatement.addBatch();// 累积SQL
            if ((i % 50 == 0 && i!= 0) || i == 99) {
                preparedStatement.executeBatch(); // 到50个执行或者最后一个
                preparedStatement.clearBatch();   // 清空Batch
            }
        }
        JdbcUtil.closeResource(connection,preparedStatement);
    }

 

在jdbc.properties 开启批处理操作支持,我试了不加这个开启也能使用

# 驱动
driverClass = com.mysql.cj.jdbc.Driver
# 连接
url = jdbc:mysql://localhost:3306/jdbc_db?serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true
# 用户
user = root
# 密码
password = 123456

# 开启批处理支持 rewriteBatchedStatements=true
# 5.1.7驱动依赖不支持批处理,降低版本或者提升版本?
# truncate table user;清空数据表

 

批量操作方式3 关闭自动提交,等全都执行成功了再提交,多次提交影响SQL的性能,这个操作还能在提高一些

    @Test
    public void blobTest3() throws SQLException {
        String sql = "insert into user(user_name,user_password) values(?,?)"; //批量操作不要在SQL语句加冒号结束
        Connection connection = JdbcUtil.getConnection();
        connection.setAutoCommit(false); // 关闭事务的自动提交
        PreparedStatement preparedStatement = connection.prepareStatement(sql);
        for (int i = 0; i < 100 ; i++) {
            // addBatch(),executeBatch(),clearBatch();
            preparedStatement.setObject(1,"演示批量操作"+i);
            preparedStatement.setObject(2,"123"+i);

            preparedStatement.addBatch();// 累积SQL
            if ((i % 50 == 0 && i!= 0) || i == 99) {
                preparedStatement.executeBatch(); // 到50个执行或者最后一个
                preparedStatement.clearBatch();   // 清空Batch
            }
        }
        connection.commit(); // 执行提交
        JdbcUtil.closeResource(connection,preparedStatement);
    }

 

以上内容来自于网络,如有侵权联系即删除
相关文章

上一篇: javascript 利用 Math.min 与 Math.max 优化逻辑判断

下一篇: java工作复习——cookie的增删查

客服紫薇:15852074331
在线咨询
客户经理