用sql语句插入blob图片文件到oracle表,并用java读取写入到文件
用sql语句插入blob图片文件到oracle表,并用java读出来放到另外一个文件里。
1.将要插入的图片文件copy到oracle server的某个目录下。
注意:一定是oracle server,而不是客户端所在的机器。
2.在数据库中创建directory.
注意:directory的大小写。如果创建directory的时候有双引号,后来引用该directory名称时则需要大小写严格保持一致;如果没有双音号,则引用时用大写。官方文档上有说明。
3.创建表并插入数据
下边语句已测试通过
注意:如果在工具中执行procedure,记得首尾添加 --/ 和 / ,否则报错。
CREATE TABLE joe.t_blob01(c1 varchar(20), photo BLOB, c_end CHARACTER(50)); create or replace directory "TEST_FILES" as '/home/oracle/testfiles'; --select * from all_directories; --/ declare b_file bfile; b_blob blob; begin insert into joe.t_blob01 values('user2@126.com',empty_blob(),'13858765437') returning photo into b_blob; b_file:=bfilename('TEST_FILES','duck01.jpg'); dbms_lob.open(b_file,dbms_lob.file_readonly); dbms_lob.loadfromfile(b_blob,b_file,dbms_lob.getlength(b_file)); dbms_lob.close(b_file); commit; end; / select * from joe.t_blob01;
4.java 读取oracle中并写到另外一个文件中。
Connection conn = null; Statement stmt = null; System.out.println(oracle_URL); try { Class.forName(oracle_DRIVER); conn = DriverManager.getConnection(oracle_URL, oracle_USER, oracle_PASS); String sql; sql = "select photo from joe.t_blob01 select_intellij " + EnvConfig.QUERY_SUFFIX; stmt = conn.createStatement(); ResultSet rs = stmt.executeQuery(sql); while (rs.next()) { //System.out.println(rs.getString(1)); oracle.sql.BLOB blob=(oracle.sql.BLOB) rs.getBlob("photo"); String despath="d:/dddd.jpg"; File file1=new File(despath); if (file1.exists()) file1.delete(); try{ InputStream in=blob.getBinaryStream(); FileOutputStream file=new FileOutputStream(despath); int len= (int) blob.length(); byte[] buffer =new byte[len]; while ((len=in.read(buffer))!=-1){ file.write(buffer,0,len); } file.close(); in.close(); }catch (Exception e){ e.printStackTrace(); } } stmt.close(); conn.close(); } catch (Exception e) { e.printStackTrace(); } finally { try { if (stmt != null) stmt.close(); } catch (SQLException se2) { se2.printStackTrace(); } try { if (conn != null) conn.close(); } catch (SQLException se) { se.printStackTrace(); } }
我踩过的坑
1. 我的oracle是docker启动的,之前为了偷懒,把图片文件放在本地宿主机,docker映射了一个文件夹,虽然可以在docker中ls能看到这个文件,但是oracle数据库中的directory是不认这个路径的。后来终于想起换个目录,然后就行了。
2.在工具中执行select * from joe.t_blob01;只会显示该图片的大小,如果用wireshark抓包,则只有图片的一些信息,比如拍摄手机的机型等,并没有完整的数据。后来从网上抄了段代码,再执行抓包,包的大小和图片文件接近,这时候就包含了所有的数据。