操作oracle数据库的LOB(大对象)类型字段

1.LOB类型的运用?

主要用于存放信息文件,数据比较大。

信息文件(十进制、二进制)、图像甚至音频信息采用数据库作为保存载体时,就需要使用lob类型数据。

2.LOB类型的分类?

LOB分为Internal Lob和External Lob。Internal Lob包含CLOB、NLOB和BLOB;External Lob只有BFILE。

我现在接触过用CLOB类型存储调接口响应回来的xml数据。

3.LOB类型的数据存储与取出?

(a)为什么lob类型的数据不能直接插入导出?

Oracle的Blob字段比较特殊,他比long字段的性能要好很多,可以用来保存例如图片之类的二进制数据。写入Blob字段和写入其它类型字段的方式非常不同,因为Blob自身有一个cursor,你必须使用cursor对blob进行操作,因而你在写入Blob之前,必须获得cursor才能进行写入。

(b)那么如何获得lob的cursor呢?

这需要你先插入一个empty的blob,这将创建一个blob的cursor,然后你再把这个empty的blob的cursor用select查询出来。这样通过两步操作,你就获得了blob的cursor,可以真正地写入blob数据了。

4.java如何操作表的LOB类型字段?

java不能直接想插入其他普通类型数据一样插入blob字段数据,因为blob相当于一个大文件块,里面有游标,需要初始化blob游标才能插入数据。所以我们要先插入一个空的blob数据,以初始化游标,然后再往这个blob字段中写入数据,来实现插入blob数据的效果。

package controller;
 
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.sql.Blob;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
 
public class DBHelper {
	private static Connection conn;                                       
	private PreparedStatement pres;                                        
	static{
		try {
			Class.forName("oracle.jdbc.OracleDriver");                     
			String url="jdbc:oracle:thin:@192.168.75.131:1521:orcl";     
			String user="jerry";
			String pwd="jerry";
			conn=DriverManager.getConnection(url,user,pwd);                
		} catch (ClassNotFoundException | SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	//写入blob数据
	public void writeBlob(){
		try {
			conn.setAutoCommit(false);                    //关闭自动提交
			String sql="insert into blobtest values(?,?,?)";//插入语句
			pres=conn.prepareStatement(sql);
			pres.setInt(1, 1);                          
			pres.setString(2, "jerry");
			pres.setBlob(3,oracle.sql.BLOB.getEmptyBLOB());//先插入空的BLOB,获取游标
			
			pres.executeUpdate();
			
			sql="select photo from blobtest where id=?";
			pres=conn.prepareStatement(sql);
			pres.setInt(1, 1); //找出ID为1的,也就是刚刚插入的
			
			ResultSet res=pres.executeQuery();
			res.next();
			Blob imageBlob=res.getBlob(1);//得到该空的blob
			
			OutputStream os = imageBlob.setBinaryStream(0); // 读取想要存储的图片文件  
                        InputStream is = new FileInputStream("G:\\jerry.jpg");  
                        // 依次读取流字节,并输出到已定义好的数据库字段中.  
                        int i = 0;  
                        while ((i = is.read()) != -1) {  
                                os.write(i); //Blob的输入流,相当于输入到数据库中
                        }  
                        os.flush();  
                        os.close();  
                        conn.commit();  
                        conn.setAutoCommit(true);// 恢复现场 
      
            if(res!=null)
            	res.close();
            if(pres!=null)
            	pres.close();
            
            System.out.println("插入成功!!!");
		} catch (SQLException | IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}
	
	public void getImage(){
		String sql="select photo from blobtest where id=?";
		
		try {
			pres=conn.prepareStatement(sql);
			pres.setInt(1, 1);
			ResultSet res=pres.executeQuery();
			
			while(res.next()){
				Blob image=res.getBlob(1);                                         //得到该blob
				
				InputStream is = image.getBinaryStream();                          //获得该blob的输出流
                FileOutputStream fos = new FileOutputStream("E:\\outputImage.jpg");  
                int i = 0;  
                while ((i = is.read()) != -1) {  
                    fos.write(i);  
                }  
                fos.flush();  
                fos.close();  
                is.close();  
			}
			System.out.println("成功输出图片!!!");
		} catch (SQLException | IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}
发布了56 篇原创文章 · 获赞 18 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_40726316/article/details/102786922