JDBC - 流式传输 ASCII 和二进制数据



PreparedStatement 对象能够使用输入和输出流来提供参数数据。这使您能够将整个文件放入可以容纳大值的数据库列中,例如 CLOB 和 BLOB 数据类型。

可以使用以下方法来流式传输数据:

  • setAsciiStream() - 此方法用于提供大型 ASCII 值。

  • setCharacterStream() - 此方法用于提供大型 UNICODE 值。

  • setBinaryStream() - 此方法用于提供大型二进制值。

除了参数占位符之外,setXXXStream() 方法还需要一个额外的参数,即文件大小。此参数通知驱动程序应使用流向数据库发送多少数据。

使用 setAsciiStream() 将 Ascii 值存储到数据库中的示例

此示例将创建一个名为 XML_Data 的数据库表,然后将 XML 内容写入此表中。在此程序中,我们定义了一些用于数据库连接、用户名、密码以及查询的静态字符串。一个查询是从 XML_Data 表中选择数据,一个查询是将数据插入 XML_data 表中,一个查询是创建 XML_Data 表,一个查询是删除表。一个字符串包含要存储在表中的 xml 数据。

使用 createXMLTable() 方法,我们首先删除表,然后创建它。在 main 方法中,使用 DriverManager.getConnection() 方法,我们准备了一个数据库连接。一旦连接准备就绪,我们就使用 connection.createStatement() 方法创建了一个 Statement 对象,并使用 connection.prepareStatement() 方法创建了一个 PreparedStatement 对象。调用 createXMLTable() 方法来创建 XML_Data 表。使用静态 XML 字符串创建了一个 ByteArrayInputStream 对象。使用 PreparedStatement.setAsciiStream() 方法,该字节流存储在 preparedStatement 中。使用 preparedStatement.execute() 方法,字节流存储在数据库中。

使用 statement.executeQuery() 方法,触发 select 查询并将结果存储在结果集中。迭代结果集并使用 getAsciiStream() 将 ascii 流作为输入流检索,并使用 ByteArrayInputStream.toString() 将此流打印到控制台。

将以下示例复制并粘贴到 TestApplication.java 中,编译并运行如下所示:

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class TestApplication {
   static final String DB_URL = "jdbc:mysql://127.0.0.1/TUTORIALSPOINT";
   static final String USER = "guest";
   static final String PASS = "guest123";
   static final String QUERY = "SELECT Data FROM XML_Data WHERE id=100";
   static final String INSERT_QUERY="INSERT INTO XML_Data VALUES (?,?)";
   static final String CREATE_TABLE_QUERY = "CREATE TABLE XML_Data (id INTEGER, Data LONG)";
   static final String DROP_TABLE_QUERY = "DROP TABLE XML_Data";
   static final String XML_DATA = "<Employee><id>100</id><first>Zara</first><last>Ali</last><Salary>10000</Salary><Dob>18-08-1978</Dob></Employee>";
   
   public static void createXMLTable(Statement stmt) 
      throws SQLException{
      System.out.println("Creating XML_Data table..." );
      //Drop table first if it exists.
      try{
         stmt.executeUpdate(DROP_TABLE_QUERY);
      }catch(SQLException se){
      }
      stmt.executeUpdate(CREATE_TABLE_QUERY);
   }

   public static void main(String[] args) {
      // Open a connection
      try(Connection conn = DriverManager.getConnection(DB_URL, USER, PASS);
         Statement stmt = conn.createStatement();
         PreparedStatement pstmt = conn.prepareStatement(INSERT_QUERY);
      ) {		      
         createXMLTable(stmt);

         ByteArrayInputStream bis = new ByteArrayInputStream(XML_DATA.getBytes());

         pstmt.setInt(1,100);
         pstmt.setAsciiStream(2,bis,XML_DATA.getBytes().length);
         pstmt.execute();

         //Close input stream
         bis.close();

         ResultSet rs = stmt.executeQuery(QUERY);
         // Get the first row
         if (rs.next ()){
            //Retrieve data from input stream
            InputStream xmlInputStream = rs.getAsciiStream (1);
            int c;
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            while (( c = xmlInputStream.read ()) != -1)
               bos.write(c);
            //Print results
            System.out.println(bos.toString());
         }
         // Clean-up environment
         rs.close();

      } catch (SQLException | IOException e) {
         e.printStackTrace();
      } 
   }
}

现在让我们按如下方式编译上述示例:

C:\>javac TestApplication.java
C:\>

运行 TestApplication 时,它会产生以下结果:

C:\>java TestApplication
Creating XML_Data table...
<Employee><id>100</id><first>Zara</first><last>Ali</last><Salary>10000</Salary><Dob>18-08-1978</Dob></Employee>
C:\>

使用 setBinaryStream() 将二进制值存储到数据库中的示例

在此示例中,我们使用在 JDBC - 数据类型 章节中创建的 JDBC_BLOB_CLOB 表。在此程序中,我们定义了一些用于数据库连接、用户名、密码以及将二进制图像插入表的查询的静态字符串。在 main 方法中,使用 DriverManager.getConnection() 方法,我们准备了一个数据库连接。一旦连接准备就绪,我们就使用 connection.prepareStatement() 方法创建了一个 PreparedStatement 对象。为了获取图像流,我们使用了 FileInputStream 从文件系统读取图像文件,并使用 PreparedStatement.setBinaryStream() 将流存储在 preparedStatement 对象中。使用 executeUpdate() 将图像存储到表中。

使用 connection.createStatement() 方法,创建一个语句以从数据库表中获取图像数据。使用 executeQuery() 触发 select 查询并将结果存储在结果集中。迭代 ResultSet 并使用 getBinaryStream() 检索一个输入流对象,然后将其用于将数据存储在字节数组中。然后将字节数组使用 FileOutputStream 存储在文件中,并显示结果。

import java.sql.*;
import java.io.*;

//This class demonstrates use of setBinaryStream
public class BinaryStreamExample {

   static final String DB_URL = "jdbc:mysql://127.0.0.1/TUTORIALSPOINT";
   static final String USER = "guest";
   static final String PASS = "guest123";
   static final String QUERY = " INSERT INTO jdbc_blob_clob (name, image) VALUES (?, ?);";
	
   public static void main(String args[]) {     
      Connection conn = null;
      PreparedStatement pstmt = null;
      Statement stmt = null;
      try{
         conn = DriverManager.getConnection(DB_URL,USER,PASS);
         System.out.println("Connection to db  established.");
             
         File image = new File("C:\\Users\\Saikat\\OneDrive\\Documents\\saikat_upwork1.jpg");
         pstmt = conn.prepareStatement(QUERY);
    
         FileInputStream fis = new FileInputStream(image);
         pstmt.setString(1, "TutorialsPoint");
         pstmt.setBinaryStream(2, fis );
         pstmt.executeUpdate();
            
         fis.close();
         System.out.println("Successfully inserted image in db");
         stmt = conn.createStatement();
         ResultSet rs = stmt.executeQuery("select name, image from jdbc_blob_clob where name='TutorialsPoint'");
         if (rs.next()) {
            InputStream ins = rs.getBinaryStream("image");
            byte byteArray[] = new byte[ins.available()];
            ins.read(byteArray);
            String filePath = "C:\\Users\\Saikat\\output_saikat_upwork1.jpg";
            FileOutputStream outPutStream = new FileOutputStream(filePath);
            outPutStream.write(byteArray);
            outPutStream.close();
            System.out.println("Binary image successfully stored at: "+ filePath);
         }
         pstmt.close();
         conn.close();
      } 
      catch(IOException ioe){
         ioe.printStackTrace();
      }
      catch(SQLException e){
         e.printStackTrace();
      }
   }
}

现在让我们按如下方式编译上述示例:

C:\>javac BinaryStreamExample.java
C:\>

运行 BinaryStreamExample 时,它会产生以下结果:

C:\>java BinaryStreamExample
Connection to db  established.
Successfully inserted image in db
Binary image successfully stored at: C:\Users\Saikat\output_saikat_upwork1.jpg

C:\>

使用 setCharacterStream() 将字符流存储到数据库中的示例

在此示例中,我们使用在 JDBC - 数据类型 章节中创建的 JDBC_BLOB_CLOB 表。在此程序中,我们定义了一些用于数据库连接、用户名、密码以及将大文本插入表的查询的静态字符串。在 main 方法中,使用 DriverManager.getConnection() 方法,我们准备了一个数据库连接。一旦连接准备就绪,我们就使用 connection.prepareStatement() 方法创建了一个 PreparedStatement 对象。为了获取字符流,我们使用了 FileReader 从文件系统读取文本文件,并使用 PreparedStatement.setCharacterStream() 将流存储在 preparedStatement 对象中。使用 executeUpdate() 将文本文件内容存储到表中。

使用 connection.createStatement() 方法,创建一个语句以从数据库表中获取图像数据。使用 executeQuery() 触发 select 查询并将结果存储在结果集中。迭代 ResultSet 并使用 getCharacterStream() 检索一个输入流对象,然后将其用于将数据存储在读取器中。使用 FileWriter 将读取器内容存储在文件中,并显示结果。

import java.sql.*;
import java.io.*;
        
// This class demonstrates use of setCharacterStream
public class JDBCCharacterStream {

   static final String DB_URL = "jdbc:mysql://127.0.0.1/TUTORIALSPOINT";
   static final String USER = "guest";
   static final String PASS = "guest123";
   static final String QUERY = " INSERT INTO jdbc_blob_clob(name, plain_text) VALUES(?,?);";
    
   public static void main(String args[]) {
        
      Connection conn = null;
      PreparedStatement pstmt = null;
      Statement stmt = null;
      try{
         conn = DriverManager.getConnection(DB_URL,USER,PASS);
         System.out.println("Connection to db  established.");
        
         pstmt = conn.prepareStatement(QUERY);
         pstmt.setString(1, "SetCharacterStream Example");
         FileReader fileReader = new FileReader("C:\\Users\\Saikat\\OneDrive\\Documents\\mysql_create_table.txt");
         pstmt.setCharacterStream(2, fileReader);
         pstmt.execute();
             
         System.out.println("Successfully inserted file data using setCharacterStream.");
             
         stmt = conn.createStatement();
         ResultSet rs = stmt.executeQuery("SELECT name, plain_text from jdbc_blob_clob where name='SetCharacterStream Example'");
         String filePath = "C:\\Users\\Saikat\\clob_output_mysql_create_table.txt";
         Reader r;
         while(rs.next()) {
            String name = rs.getString("Name");
            r = rs.getCharacterStream("plain_text");
                
            FileWriter writer = new FileWriter(filePath);
            int i=0;
            while ((i=r.read())!=-1) {
               writer.write(i);
            }
               writer.close();
         }
         
         System.out.println("Successfully retrieved file using getCharacterStream at " + filePath ); 
         pstmt.close();
         stmt.close();
		 conn.close();
             
      }catch(IOException ioe){
         ioe.printStackTrace();
      }catch(SQLException sqle){
         sqle.printStackTrace();
      }
   }
}

现在让我们按如下方式编译上述示例:

C:\>javac JDBCCharacterStream.java
C:\>

运行 JDBCCharacterStream 时,它会产生以下结果:

C:\>java JDBCCharacterStream
Connection to db  established.
Successfully inserted file data using setCharacterStream.
Successfully retrieved file using getCharacterStream at C:\Users\Saikat\clob_output_mysql_create_table.txt

C:\>
广告