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:///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:///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:///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:\>
廣告