六、JDBC-處理CLOB與BLOB

Blob 是一個二進制大型對象(文件),在MySQL中有四種 Blob 類型,區別是容量不一樣

TinyBlob 255B
Blob 65KB
MediumBlob 16MB
LongBlob 4GB

插入數據

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

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

public class BlobTest {

    private Connection connection;
    private ResultSet resultSet;
    private PreparedStatement preparedStatement;

    @BeforeEach
    public void start() throws Exception {
        Properties properties = new Properties();
        InputStream in = this.getClass().getClassLoader().getResourceAsStream("jdbc.properties");
        properties.load(in);

        String driver = properties.getProperty("driver");
        String jdbcUrl = properties.getProperty("jdbcUrl");
        String user = properties.getProperty("user");
        String password = properties.getProperty("password");

        Class.forName(driver);

        connection = DriverManager.getConnection(jdbcUrl, user, password);
    }

    @AfterEach
    public void end() throws Exception {
        if (resultSet != null) {
            resultSet.close();
        }
        if (preparedStatement != null) {
            preparedStatement.close();
        }
        if (connection != null) {
            connection.close();
        }
    }

    /**
     * 插入 BLOB 類型的數據必須使用 PreparedStatement:由於 BLOB 類型的數據時沒法使用字符串拼寫的。
     * 可封裝成 Blob 對象,也可直接使用IO流,調用 setBlob 或 setBinaryStream
     */
    @Test
    public void testInsertBlob() {
        try {
            String sql = "INSERT INTO blob_test (file, name) VALUES (?,?)";
            preparedStatement = connection.prepareStatement(sql);

            Blob blob = connection.createBlob();
            InputStream in = this.getClass().getClassLoader().getResourceAsStream("file.png");
            OutputStream out = blob.setBinaryStream(1);

            byte[] buffer = new byte[1024];
            int len = 0;
            while ((len = in.read(buffer)) != -1) {
                out.write(buffer, 0, len);
            }
            in.close();
            out.close();

            preparedStatement.setBlob(1, blob);
//            preparedStatement.setBlob(1, in);
//            preparedStatement.setBinaryStream(1, in);

            preparedStatement.setString(2, "ABCDE");
            preparedStatement.execute();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

讀取數據

/**
 * getBlob 方法讀取到 Blob 對象,調用 Blob 的 getBinaryStream() 方法獲得輸入流
 * 或者直接 getBinaryStream 獲得 IO 流
 */
@Test
public void testReadBlob() {
    try {
        String sql = "SELECT id, file, name FROM blob_test WHERE id = ?";
        preparedStatement = connection.prepareStatement(sql);
        preparedStatement.setInt(1, 13);
        resultSet = preparedStatement.executeQuery();

        if (resultSet.next()) {
            int id = resultSet.getInt(1);
            Blob file = resultSet.getBlob(2);
            String name = resultSet.getString(3);


            InputStream in = file.getBinaryStream();
//                InputStream in = resultSet.getBinaryStream(2);
            System.out.println(name + "\t" + in.available());

            OutputStream out = new FileOutputStream("newfile.jpg");

            byte[] buffer = new byte[1024];
            int len = 0;
            while ((len = in.read(buffer)) != -1) {
                out.write(buffer, 0, len);
            }
            in.close();
            out.close();
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}

MySQL 中無 Clob 類型,在 Oracle 中才有,能夠在 MySQL 用 text 或者 varchar 替換,它至關於String

與 Blob 類型對比,MySQL官方文檔

Clob Type Blob Type Storage Required
TINYTEXT TINYBLOB L + 1 bytes,其中 L < 2**8  (255 B)
TEXT BLOB L + 2 bytes,其中 L < 2**16 (64 K)
MEDIUMTEXT MEDIUMBLOB L + 3 bytes,其中 L < 2**24 (16 MB)
LONGTEXT LONGBLOB L + 4 bytes,其中 L < 2**32 (4 GB)

插入數據

/**
 * 就是插入字符串
 */
@Test
public void testInsertClob() {
    try {
        Clob myClob = connection.createClob();
        Writer clobWriter = myClob.setCharacterStream(1);
        String str = readFile("clob.txt", clobWriter);
        myClob.setString(1, str);
        System.out.println("Clob 的長度:" + myClob.length());

        String sql = "INSERT INTO clob_test (file, name) VALUES(?,?)";
        preparedStatement = connection.prepareStatement(sql);
        preparedStatement.setClob(1, myClob);
//            preparedStatement.setString(1,str);
        preparedStatement.setString(2, "ABCDE");
        preparedStatement.executeUpdate();
    } catch (Exception e) {
        e.printStackTrace();
    }
}

private String readFile(String fileName, Writer writerArg) throws IOException {
    BufferedReader br = new BufferedReader(new FileReader(this.getClass().getClassLoader().getResource(fileName).getPath()));
    String nextLine = "";
    StringBuffer sb = new StringBuffer();
    while ((nextLine = br.readLine()) != null) {
        writerArg.write(nextLine);
        sb.append(nextLine);
    }
    return sb.toString();
}

讀取數據

@Test
public void testReadClob() {
    try {
        String sql = "SELECT id, file, name FROM clob_test WHERE id = ?";
        preparedStatement = connection.prepareStatement(sql);
        preparedStatement.setInt(1, 3);
        resultSet = preparedStatement.executeQuery();

        if (resultSet.next()) {
            int id = resultSet.getInt(1);
            Clob file = resultSet.getClob(2);
            String name = resultSet.getString(3);

            InputStream in = file.getAsciiStream();
            System.out.println(name + "\t" + in.available());

            StringBuilder sb = new StringBuilder();
            byte[] buffer = new byte[1024];
            while (in.read(buffer) != -1) {
                sb.append(new String(buffer));
            }
            in.close();

//                String str = resultSet.getString(2);
            System.out.println(sb);
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}

 

 


Oracle JDBC 官方文檔

相關文章
相關標籤/搜索