Java将文件导入到Oracle的BLOB字段

2020-08-27  本文已影响0人  拼搏男孩

虽然说现在大部分公司都把文件存放在一个单独的文件服务器上,在数据库中存的是图片的地址,但是还有一些比较落后的公司直接把图片放在数据库中,这种方式比较占用数据库容量,而且不方便检索,前台也不好处理,但是我就遇到了这样一个需求,将本地文件导入到Oracle数据库中。

1、添加依赖

<dependencies>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.22</version>
        </dependency>
        <dependency>
            <groupId>com.oracle</groupId>
            <artifactId>ojdbc6</artifactId>
            <version>11.2.0.2.0</version>
        </dependency>
    </dependencies>

我创建的是一个普通的maven项目。由于只需要和数据库交互,所以只用添加数据库驱动就可以了,我们开发用的是Oracle数据库,所以用的是Oracle驱动,如果是MySQL数据库就需要使用MYSQL驱动。我还添加了druid的依赖,其实是没有必要的。

2、配置文件

jdbc.properties

driver=oracle.jdbc.OracleDriver
url=jdbc:oracle:thin:@192.168.6.222:1521:sid
userName=test
password=test

这个配置文件保存jdbc连接的配置信息,放在resources目录下。

3、工具类

import com.alibaba.druid.pool.DruidDataSource;

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

public class JDBCUtils {
    private static DruidDataSource dataSource = new DruidDataSource();
    static{
        try {
            //从本地文件中读取配置信息
            Properties properties = new Properties();
            //获取当前类的根路径 , 读取配置文件
            InputStream is = JDBCUtils.class.getClassLoader().getResourceAsStream("jdbc.properties");
            properties.load(is);
            dataSource.setDriverClassName(properties.getProperty("driver"));
            dataSource.setUrl(properties.getProperty("url"));
            dataSource.setUsername(properties.getProperty("userName"));
            dataSource.setPassword(properties.getProperty("password"));
            dataSource.setMaxActive(150);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static Connection getConnection() {
        Connection cn = null;
        try {
            cn = dataSource.getConnection();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return cn;
    }
    public static void close(Statement st, Connection cn){

       close(null,st,cn);
    }
    public static void close(ResultSet rs, Statement st, Connection cn){
        //关闭连接
        if(rs!=null){
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if(st!=null){
            try {
                st.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if(cn!=null){
            try {
                cn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}

JDBCUtils工具类用于读取配置文件、获取连接、关闭连接。

4、主类

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.PrintStream;
import java.sql.*;

/**
 * @author huwen
 */
public class ImportImage {

    private Connection conn;
    /**
     * 向表中插入图片
     *
     * @param path 图片所在的路径
     * @return 整形 判断成功或失败
     */
    public int insertImage(File path) throws Exception {
        int i = 0;
        Statement st = null;
        ResultSet rs = null;
        conn=JDBCUtils.getConnection();
        //设置数据库为不自动提交,必须的一步
        conn.setAutoCommit(false);
        //先插入一个空对象,这里我调用了Empty_BLOB()函数
        st = conn.createStatement();
        //先插入一个空对象,这里我调用了Empty_BLOB()函数
        String paperNo = path.getName().split("\\.")[0];
        String insertSql = "insert into TF_F_CARDPARKPHOTO_SZ_TMP (parpno,picture,operatetime) values ('"+paperNo+"',Empty_BLOB(),sysdate)";
        i = st.executeUpdate(insertSql);
        //以行的方式锁定
        String selectSql =  "select picture from TF_F_CARDPARKPHOTO_SZ_TMP where parpno= '"+paperNo+"' for update";
        rs = st
                .executeQuery(selectSql);

        if (rs.next()) {
            //得到流
            oracle.sql.BLOB blob = (oracle.sql.BLOB) rs.getBlob(1);
            //从得到的低级流构造一个高级流
            if(blob==null){
                System.out.println(paperNo);
            }
            PrintStream ps = new PrintStream(blob.getBinaryOutputStream());
            BufferedInputStream bis = new BufferedInputStream(
                    new FileInputStream(path));
            byte[] buff = new byte[1024];
            int n = 0;
            //从输入到输出
            while ((n = bis.read(buff)) != -1) {
                ps.write(buff, 0, n);
            }
            //清空流的缓存
            ps.flush();
            //关闭流,注意一定要关
            ps.close();
            bis.close();
        }
        conn.commit();
        JDBCUtils.close(rs,st,conn);
        return i;
    }

    public static void main(String[] args) throws Exception {
        ImportImage test=new ImportImage();
        File file = new File("C:\\Users\\huwen\\Documents\\1109");
        for (File f : file.listFiles()) {
            test.insertImage(f);
        }
        System.out.println("OK");

    }
}

首先要保证表中没有数据,并且有一个字段数据类型为BLOB。这种做法的原理是先向表中插入一个Empty_Blob()函数创建的数据,然后以行的方式锁定读取该字段信息,从磁盘中读取文件写入。中间一定要注意关闭自动提交,执行完后进行手动提交

上一篇下一篇

猜你喜欢

热点阅读